我的一个输入文件,如下所示:
Stroustrup, Bjarne 8 8 -1 -1 -1
Lovelace, Ada 1 60 14 43 -1
von Neumann, Jon 77 48 65 -1 -1
Wirth, Niklaus 51 59 -1 -1 -1
Wozniak, Steve 81 -1 -1 -1 -1
Babbage, Charles 31 92 -1 -1 -1
Hopper, Grace 76 -1 -1 -1 -1
Bird, Tweety -99 -99 -99 -99 -99
Sylvester 77 39 -1 -1 -1
我当前的程序使用
流式传输数据infile >> lastName >> firstName >> ...
不幸的是,这仅适用于其他输入文件,因为每一行实际上都有一个姓氏和名字。这里,由于第三行中的两部分姓氏和最后一行中的第一个名称,其余数据无法流式传输。有没有什么方法可以从行的开头抓取一个字符串,直到达到一个整数?
答案 0 :(得分:3)
在解析输入文件时,您几乎永远不会得到直接使用原始流来用值填充变量的解决方案。输入格式可能不同,可能会出现错误......在这种情况下,更好的方法是 逐行读取输入并分别处理每一行 。在处理每一行时,您可以构造一个临时istringstream
,您可以使用它来读取它中的单词,并检查该单词是否可以转换为数字(如果0
不是有效值,请使用{ {3}}):
std::string line;
while (std::getline(infile,line))
{
if (line.empty()) continue;
std::istringstream is(line);
std::string word;
while (is >> word)
{
int val = std::atoi(word);
if (val)
{
// TODO: number
}
else
{
// word
}
}
}
或者,您可以考虑使用std::atoi
来检查单词的第一个字符是否为数字:
if (std::isdigit(word[0])) ...
答案 1 :(得分:0)
您是否可以控制输入文件的格式?看到你们两个都有两部分名称(例如“von Neumann”)或一个名字(即不是第一个和最后一个,例如“西尔维斯特”)的选项,解析起来就不必要了。如果您可以引用名称,例如"von Neumann", Jon
,那么事情可能会容易得多。
一种方法可能包括:
#define DELIM 'c'
ostringstream namestream;
infile.get(namestream, DELIM);
string name = namestream.str();
这将从infile获取字符串,直到达到字符DELIM。查看您的文件,它看起来像名称部分和名字/姓氏用空格或逗号后跟空格分隔,其中名称末尾和第一个数字之间的间隙可能是标签。如果是这种情况,您可以使用制表符('\t'
)作为分隔符。
不幸的是,这种方法只支持DELIM作为单个字符,而不是一组字符。因此,如果您想支持负数,您将无法读取第一个数字(或“数字或' - '”。