C++如何读取流直到行末

3

我希望从文件中读取如下格式的输入:

sphere 3 2 3 4
pyramid 2 3 4 12 3 5 6 7 3 2 4 1 2 3
rectangle 2 3 4 1 9 12

我想要做类似以下操作:

char name[64];  
int arr[12];  
ifstream file (..);  
while(file)  
{   
file >> name;  
    while( //reach end of line) 
        file >> arr[i]
}

您可以看到,我不知道会输入多少个整数,这就是为什么我想在新行停止。我使用getline实现了这一点,然后拆分了行,但他们告诉我只能使用 >> 运算符来完成。

注意:我不能使用 std::stringstd::vector


1
查找“C++解析CSV”(并且使用空格作为分隔符) - user2249683
@DieterLücking 我已经读了很长时间,但还是做不到。你能给我演示一下吗? - Gigata
看一下我对另一个问题的回答。你可以采用类似的策略。 - R Sahu
我可以做到,而且我是通过逐行阅读、分割和解析每一行来完成的。但他们告诉我有一种更简单的方法,但我找不到它。 - Gigata
4
我不能使用std::string--是谁想出这些荒谬的限制?还有什么其他东西不能用? - PaulMcKenzie
显示剩余7条评论
2个回答

5
简单的方法是使用类似于std::ws的操作器,但不是跳过所有空格,而是在遇到换行符时设置std::ios_base::failbit。这个操作器将被用来跳过隐式空格(除了换行符)。例如(代码没有测试,但我认为像下面这样去掉错误和编译错误应该可以工作):
std::istream& my_ws(std::istream& in) {
    std::istream::sentry kerberos(in);

    while (isspace(in.peek())) {
        if (in.get() == '\n') {
            in.setstate(std::ios_base::failbit);
        }
    }
    return in;
}
// ...
char name[64];
int  array[12];
while (in >> std::setw(sizeof(name)) >> name) {  // see (*) below
    int* it = std::begin(array), end = std::end(array);
    while (it != end && in >> my_ws >> *it) {
        ++it;
    }
    if (it != end && in) { deal_with_the_array_being_full(); }
    else {
        do_something_with_the_data(std::begin(array), it);
        if (!in.eof())  { in.clear(); }
    }
}

我的个人猜测是该任务要求将值读入char数组,然后使用atoi()strol()进行转换。我认为这将是一种无聊的解决方案。
(*) 绝不要甚至在示例代码中,使用格式化输入运算符与char数组array不设置允许的最大大小!可以通过设置流的width()来设置大小,例如使用操纵器std::setw(sizeof(array))。如果在使用格式化输入运算符与char数组时width()0,则会读取任意数量的非空格字符。这可能会导致数组溢出并成为安全问题!从本质上讲,这是C ++拼写C的gets()的方式(现已从C和C ++标准库中删除)。

1
我想你可以使用peek方法:
while (file)
{
    file >> name;
    int i = 0;
    while(file.peek() != '\n' && file.peek() != EOF) {
        file >> arr[i++];
    }
}

如果值之间有多个空格,会发生什么? - Dietmar Kühl
@DietmarKühl 嗯,但是多个空格有什么问题吗? - Edgar Rokjān
问题在于换行符可能会被一个字符所跟随,而你的换行符测试不会触发。 - Dietmar Kühl
@DietmarKühl 哦,现在我明白了。我只是将OP的输入文件作为示例使用,没有对行末空格或类似内容做出任何额外的假设... - Edgar Rokjān
我想到了类似的东西,但它不起作用,我认为这是因为在Windows下换行被标记为\r\n :D - Gigata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接