我有以下代码,用于分割字符串并将其插入数组:
char *t;
char *tmpLine = (char *)line.c_str();
t = strtok(tmpLine, "\t");
int counter = 0;
while(t != NULL) {
tempGrade[counter] = atoi(t);
counter++;
t = strtok(NULL, "\t");
}
但由于某种原因,line
的最后一个条目被忽略而未插入。也行是:
string line = "1 90 74 84 48 76 76 80 85";
注意:空格是原始文件中的制表符空间(\ t)。
答案 0 :(得分:5)
因为您已将此问题标记为C ++。我会说完全避免这样做,看看this接受的答案。
答案 1 :(得分:3)
你的代码错了,它会让我眼前一亮。
char *tmpLine = (char *)line.c_str();
首先,你是(除非我错了)丢弃了std :: string的常量,这是一个非常糟糕的主意。无论如何,抛弃修改尝试的常量气味......
t = strtok(tmpLine, "\t");
我们在这里......
您正在修改std::string
提供的缓冲区,因为strtok
会破坏为其提供的字符串。
不好主意:您不是std::string
内部缓冲区的所有者,因此您不应该修改它(您不想破坏您的字符串,并引发错误,想要你吗?),
返回代码:
t = strtok(tmpLine, "\t");
好的,您正在使用strtok
,这不是可重入的功能。
我不知道你正在使用什么编译器,但我想大多数会有更安全(即不那么愚蠢)的选择。例如,Visual C ++提供strtok_s
。如果您没有提供,则最佳解决方案是编写您自己的strtok
,或使用其他标记化API。
事实上,strtok
是为数不多的反例之一,而不是重新发明轮子":在这种情况下,重写自己将永远比原来更好标准C函数,如果你有一些C或C ++经验。
其他人提供了有关替代方案的见解,甚至是您提供的不完整代码示例似乎完整的事实,因此我将在此处停止我的分析,让您考虑他们的答案。
我不知道你的代码是什么,但这是完全错误的,即使你报告的错误(遗失的令牌)不存在也是如此。不要在生产代码上使用它。
答案 2 :(得分:2)
但你可以给我一个快速的黑客攻击吗?因为这不是一个重要的项目,我必须改变很多,就像在那个问题中那样做
不,你没有。假设tempGrade
是int
数组,这会做同样的事情:
istringstream iss(line);
int counter = copy(istream_iterator<int>(iss),
istream_iterator<int>(),
tempGrade) - tempGrade;
但最好将tempGrade
更改为vector
并使用与Moo-Juice相关联的答案中的代码。
答案 3 :(得分:0)
正如其他人所说,我建议你采取the recommended C++ approach to this problem。
但我尝试了你的代码,我不知道它有什么问题。我不会在我的问题上重复你的问题:
1
90个
74个
84个
48个
76个
76个
80个
85
也许您打印循环的迭代太短,或者您的tempGrade
数组太小?或许你最后的“标签”可能不是一个标签字符?
这是我编译以检查此代码的代码。
#include<iostream>
int main(int argc, char* argv[])
{
std::string line = "1\t90\t74\t84\t48\t76\t76\t80\t85";
char *t;
char *tmpLine = (char *)line.c_str();
t = strtok(tmpLine, "\t");
int counter = 0;
int tempGrade[9];
while(t != NULL) {
tempGrade[counter] = atoi(t);
counter++;
t = strtok(NULL, "\t");
}
for(int i = 0; i < 9; ++i) {
std::cout << tempGrade[i] << "\n";
}
}
答案 4 :(得分:0)
这是一个非常简单的示例,展示了如何使用流提取运算符和vector
以更惯用的C ++方式执行此操作:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
void parse(string line)
{
stringstream stream(line);
int score;
vector<int> scores;
while (stream >> score)
scores.push_back(score);
for (vector<int>::iterator itr = scores.begin(); itr != scores.end(); ++itr)
cout << *itr << endl;
}
int main(int argc, char* argv[])
{
parse("1\t90\t74\t84\t48\t76\t76\t80\t85");
return 0;
}