2
#include <iostream>
#include <string.h>
using namespace std;

int main() {
char *tok;
string s = "Ana and Maria are dancing.";
tok = strtok(s.c_str(), " ");
while(tok != NULL) {
    cout << tok << " ";
    tok = strtok(NULL, " ");
}
return 0;
}

そして、私はこのエラーが発生しています:

:9:29: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
In file included from ceva.cc:2:0:
348:14: error: initializing argument 1 of ‘char* strtok(char*, const char*)’ [-fpermissive]"
4

2 に答える 2

4

strtok()はその解析において破壊的です (つまり、解析している間に解析している文字列に書き込みchar*ます) const char*

c_str()返されるconst char*バッファの内容にユーザーが書き込むことを想定していないため、 a を返します。

解析を行う方法は、作業したいバッファをstrdup() (つまりコピー) して解析することです。

char* buf = strdup(s.c_str());
tok = strtok(buf, " ");
...

コピーが完了したら、忘れずにコピーを解放してください。

于 2013-05-11T09:15:13.077 に答える
2

問題は、オブジェクトがカプセル化された文字列が格納されているバッファーの所有者であると想定されているため、がc_str()返されることです。const char*stringstring

一方、strtok()(non- const)へのポインタchar、つまり aを受け入れますがchar*、これがコンパイラの不平です: 変更できないものを、そのものを変更したい関数に渡そうとしています。

std::stringとにかく使用しているので、C ++ 11でより慣用的なより良いアプローチを提案する場合は、代わりに次のことを行います。

#include <iostream>
#include <string>

int main() 
{
    std::string s = "Ana and Maria are dancing";

    std::string::size_type start = 0;
    std::string::size_type pos = s.find(" ");
    while (pos != std::string::npos)
    {
        std::string tok = s.substr(start, pos - start);
        std::cout << tok << " ";

        start = pos + 1;
        pos = s.find(" ", start);
    }
}

上記のコードは、次のディレクティブも削除しました。

using namespace std;

名前空間に属するエンティティとの名前の衝突を簡単に引き起こすため、(特にグローバル名前空間スコープに配置された場合) 悪いプログラミング手法と一般的に見なされstdます。

于 2013-05-11T09:14:13.047 に答える