0

こんにちは、以下の例のように文字列のトークン化を行っています。ただし、whileループ内では、たとえば文字「a」を「hellow」に変更します。myVar [i]に割り当てる前にpchを変更しようとすると、セグメンテーション違反が発生します。どうすればいいですか?

    map <int, char*> myVar;
    char str[] ="- This, a sample string.";
    char * pch;
    printf ("Splitting string \"%s\" into tokens:\n",str);
    pch = strtok (str," ,.-");
    int i = 0;

    while (pch != NULL)
    {
        printf ("%s\n",pch);

        //modify token value
        stringstream strStream;
        strStream << "hello_world";

        char newStr[7] = {0};
        memcpy(newStr, strStream, 7);

        myVar[i] = (char*)newStr;
        pch = strtok (NULL, " ,.-");
        i++;
     }
4

2 に答える 2

2

whileループ内に2つのバグがあります。

stringstream1)含まれているデータではなく、それ自体をに渡しますmemcpy()stringstream::operator void*()変換演算子に依存しています。実際のデータを指していないので、そのポインタを尊重することは想定されていません。stringstreamこれは、が有効かどうかを示す単なるフラグです。stringstreamにデータを渡すには、最初にmemcpy()そのメソッドを呼び出してデータを含むデータを取得してから、そのメソッドを呼び出してそのデータをに渡す必要があります。str()std::stringc_str()memcpy()

2)に値を挿入するときは、毎回std::mapローカル変数を挿入します。char[]それchar[]はすぐにスコープから外れstd::map、スタック上のランダムな場所へのポインタが含まれたままになります。示したコードを考えると、char[]バッファーは毎回同じスタックスペースを再利用する可能性があります。

std::stringC ++を使用しているので、実際には、、などのC++指向のものを使用する必要がありますstd::cout

これを試して:

std::map <int, std::string> myVar;
std::string str = "- This, a sample string.";
std::cout << "Splitting string \"" << str << "\" into tokens:" << std::endl;
size_t start = 0;
int i = 0;

do
{
    std::string token;

    size_t pos = str.find_first_of(" ,.-", start);
    if (pos != std::string::npos)
    { 
        token = str.substr(start, pos-start);
        start = pos + 1;
    }
    else
    {
        token = str.substr(start);
        start = std::string::npos;
    }

    std::cout << token << std::endl;

    //modify token value
    myVar[i] = "hello_world";

    ++i;
 }
 while (start != std::string::npos);
于 2012-11-06T02:31:55.950 に答える
0

ご覧のとおり、strtokは渡された文字列を変更します。これは、文字列定数で使用しようとすると、多くの場合、セグフォールトになります。これは、メモリを実際に変更する必要がないためです。

これを回避するために私が使用する方法は、文字列の複製に対して常にstrtokを使用することです。

char *srcStr = "Some constant text";
char *tmpStr = strdup(srcStr);
//...
//some operations involving strtok
//...
free(tmpStr);
于 2012-11-06T01:51:32.443 に答える