从输入文件中获取字符串直到整数? C ++

时间:2013-11-21 00:17:51

标签: c++ string ifstream

我的一个输入文件,如下所示:

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 >> ...

不幸的是,这仅适用于其他输入文件,因为每一行实际上都有一个姓氏和名字。这里,由于第三行中的两部分姓氏和最后一行中的第一个名称,其余数据无法流式传输。有没有什么方法可以从行的开头抓取一个字符串,直到达到一个整数?

2 个答案:

答案 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作为单个字符,而不是一组字符。因此,如果您想支持负数,您将无法读取第一个数字(或“数字或' - '”。