在循环中使用isstringstream作为标记器
Using isstringstream as a tokenizer in a loop
本文关键字:isstringstream 循环 更新时间:2023-10-16
我想要一些帮助来理解如何处理isstringstream对象。
我正在尝试标记文件的每一行,以便我可以在检查标记中的某些数据值后以另一种格式重写它。我在一个tokenVector中加载每一行,并迭代vector。我的代码可以工作,但我担心的是,我必须为每次迭代实例化一个isstringstream对象,否则它不能工作。这感觉不对。这是我的代码:
std::string line;//each file line
std::ifstream myFile (info.txt.c_str());
if(myFile.is_open()){
getline(myFile, line);
std::vector<std::string> tokenVector;
//create a isstringstream object for tokenizing each line of the file
std::istringstream hasTokens(line);
while(hasTokens)
{
std::string substring;
if(! getline(hasTokens, substring,','))
break;
tokenVector.push_back(substring);
}
//look for some known header names for validation
if(!tokenVector.empty()){
if(!(tokenVector[0]=="Time")&&(tokenVector[1] == "Group")&&(tokenVector[2]=="Perception")&&(tokenVector[3] == "Sign")){
setErrorMesssage("Invalid Header in myFile");
return false;
}
tokenVector.clear();
}
//clear the isstringstream object
hasTokens.str(std::string());
//if header validates, do rest of file
while(myFile.good()){
getline(myFile , line);
//break line into tokens using istringstream
std::istringstream hasTokens(line);
//reload the vector of tokens for each line
while(hasTokens)
{
std::string substring;
if(! getline(hasTokens, substring,','))
break;
tokenVector.push_back(substring);
}
otherFileWritingFunction(tokenVector[0], tokenVector[2], tokenVector[4]);
tokenVector.clear();
hasTokens.str(std::string());
}//end while
}//end if is_open
这段代码可以工作,但它不正确,因为我应该只实例化一次isstringstream(我认为)。如果我尝试"hasTokens.str(line)"为每个迭代只使用hasTokens的原始实例化,就像一些例子所建议的那样,它不起作用,所以我真的很感谢一个建议。
谢谢
不,你的担心是多余的。在需要时创建一个新的流对象,并在完成后处理它。这就是c++的精神所在。每个目标对应一个目标,每个目标对应一个目标(误引弗兰克·赫伯特)。构造字符串流没有什么"昂贵"的,当你重新分配现有字符串流的字符串数据时也不会发生。
你的代码是非常嘈杂和冗余的。标准的习惯用法是这样的:
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
std::string token;
while (iss >> token) { /* do stuff */ }
}
压缩版本(有人会称之为滥用):
for (std::string line; std::getline(infile, line); )
{
std::istringstream iss(line);
for (std::string token; iss >> token; ) { /* ... */ }
}
第二个std::istringstream
声明具有完全不同的作用域,并且在每次迭代中构造,因此hasTokens.str(std::string());
没有影响。
如果在while循环中使用hasTokens.str(line)
,则可以重用相同的对象