1

コードを変更しましたが、コンパイル中にこれらのエラーが発生しました。

`check.cpp: In function ‘int main()’:`

check.cpp:14:55: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]

/usr/include/getopt.h:152:12: error: initializing argument 2 of ‘int getopt(int, char* const*, const char*)’ [-fpermissive]

int main() {

string text="-f  input.gmn -output.jpg";
int argc=text.length();
cout<<"argc: "<<argc<<endl;
char const * argv = text.c_str();
cout<<"argv: "<<argv<<endl;
int c = getopt (argc, &argv, "f:s:o:pw:h:z:t:d:a:b:?");
return 0;
}
4

3 に答える 3

5

text.c_str()を に変換するためにstd::string使用できますconst char*ここを参照してください。

私の答えを詳しく説明すると、必要な配列を作成する方法はたくさんありますが、これについては既にhereherehere、およびhereで説明されています。new/またはmallocSTLの集中的な使用を伴わない、および//そうでないものを非常に高速に実行する、問題の簡単な解決策はistringstream次のようになります。back_insertercopy

/* variables. */
std::vector< char* > argv;
int i, argc, state;
char c;

/* convert string to char string with automatic garbage collection. */
std::vector< char > tokens(text.begin(), text.end());
tokens.push_back(0);

/* tokenize string with space. */
for (state=0, argc=0, i=0; (c=tokens[i]); i++) {
    if (state) {
        if (c == ' ') {
            tokens[i]=0;    
            state=0;        
        }           
    } else {
        if (c != ' ') {
            argv.push_back(&tokens[i]);
            argc++;         
            state=1;        
        }           
    }       
}   

/* print argv. */
std::cout << "argc: " << argc << std::endl;
for (i=0; i < argc; i++) {
    std::cout << "argv[" << i << "]: " << argv[i] << std::endl;
}   

/* call getopt. */
c = getopt(argc, &argv[0], "f:s:o:pw:h:z:t:d:a:b:?");

これは単なる例ですが、この種のコードの利点の 1 つは、スペースだけでなく他の文字を区切り文字として使用できることと、割り当てられたメモリの解放を気にする必要がないことですstd::vector。これは、関数の終了時に行われるためです。

于 2012-05-08T12:38:28.697 に答える
4

コードの最初のバグは比較です:

for (int i=0; i<=stringLength; i++) {
   arv[i]=text[i]; 
}

i< stringLengthの代わりに使用しi<=stringLengthます。

2 番目のバグは、arvnull で終了しないことです。

両方のバグを修正すると、コードは次のようになります。

for (int i=0; i < stringLength; i++) {
   arv[i]=text[i]; 
}
arv[stringLength] = '\0';

ちなみに、 の正しい関数シグネチャgetopt次のとおりです。

int getopt(int argc, char * const argv[], const char *optstring);

これは、2 番目と 3 番目の引数を としconstます。つまり、次のことができます。

 char const * s = text.c_str();
 int c = getopt (argc, &s, "f:s:o:pw:h:z:t:d:a:b:?");

手動ループを使用して、変換の必要はありません。

于 2012-05-08T12:40:04.600 に答える
4

つまり、文字列への 100 個のポインターを含む配列 argv があり、そのうち最初のポインターのみが設定されています。argv[1] は何も設定されていないため、ランダムな場所を指しています。そしてこの場合、違法です。

さらに、 getoption が期待するものは、次のようになります。

argv[0] = "progname";
argv[1] = "-f";
argv[2] = "input.gmn"
argv[3] = "-output.jpg"
argv[4] = 0

末尾の =0 に注意して、メモリのランダムなビットによる getoption チャージを停止します。

于 2012-05-08T12:43:31.030 に答える