Strtok在行尾返回额外数据

时间:2013-03-17 03:23:02

标签: c++ string char strtok

我几个小时一直在搞乱这段代码,我正在寻找一些建议。我正在使用strtok从字符串中获取单词,但我在每行的末尾都会获得额外的数据。我有以下代码:

cout << "\n\n6. Load File:\n";
        getline(cin, inFile);
        inFile = path + inFile;
        myfile.open(inFile.c_str());
            while (myfile.is_open() == false)   //check to make sure file exists
            {
                cout << "\nPlease enter in a valid file name: ";
                getline(cin,inFile);
                inFile = path + inFile;
                myfile.open(inFile.c_str());
            }
                getline (myfile,line);
                while ( myfile.good() )     //while the file is running, run below code
                {
                    getline (myfile,line);
                    //cout << line;
                    char str[line.length()];
                    char * pch;
                    for (int i=0;i<line.size();i++) { //creates a char array from characters
                        str[i]=line[i];
                    }
                    pch = strtok(str," ,-!?\r\t\f\v\n\0|/\\_"); //eliminates whitespace,etc in char array
                    while (pch != NULL)
                    {
                        printf ("%s\n",pch);
                        pch = strtok (NULL, " ,-!?\r\t\f\v\n\0|/\\_");  //grabs next word
                    }

                }
        myfile.close();

现在这段代码给了我想要的单词输出,但每行末尾的内存中随机疯狂值。见下文:

加载文件:
cars1.txt
老爷车

3402.99 \ 244 \ 363P
Rustbucket
布朗
44.99的 P
柠檬

4226.99 99P

请帮助,非常感谢!

2 个答案:

答案 0 :(得分:1)

C中,字符串最后必须有NUL(0)。你需要添加它。

(这也意味着您的令牌字符串中的\0被视为该字符串的结尾,并且将忽略以下字符。这将使其符合您对空白的评论,但可能不是你真正想要的是什么。)

最简单的解决方案:使用strdup复制字符串。

char* tmp_copy = strdup(line.c_str());
for (char* pch = strtok(tmp_copy," ,-!?\r\t\f\v\n\0|/\\_");
     pch;
     pch = strtok (NULL, " ,-!?\r\t\f\v\n\0|/\\_")) {
   printf ("%s\n",pch);
}
free(tmp_copy);

更好的解决方案:使用boost::tokenizer

答案 1 :(得分:0)

您需要空终止str。您一次将line复制到str个字符,但不是终止空字符。

试试这个:

char str[line.length()+1];
char * pch;
for (int i=0;i<line.size();i++) {
    str[i]=line[i];
}
str[line.size()+1] = '\0';     // null terminator

或者更简单,只需初始化str

char str[line.length()+1] = {};  // initialize to all nulls
char * pch;
for (int i=0;i<line.size();i++) {
    str[i]=line[i];
}