我几个小时一直在搞乱这段代码,我正在寻找一些建议。我正在使用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
请帮助,非常感谢!
答案 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];
}