【问题标题】:Unexpected behaviour of getline() with ifstreamgetline() 与 ifstream 的意外行为
【发布时间】:2011-03-31 11:31:09
【问题描述】:

为了简化,我尝试使用 ifstream 类及其 getline() 成员函数读取 CSV 文件的内容。这是这个 CSV 文件:

1,2,3
4,5,6

还有代码:

#include <iostream>
#include <typeinfo>
#include <fstream>

using namespace std;

int main() {
    char csvLoc[] = "/the_CSV_file_localization/";
    ifstream csvFile;
    csvFile.open(csvLoc, ifstream::in);
    char pStock[5]; //we use a 5-char array just to get rid of unexpected 
                    //size problems, even though each number is of size 1
    int i =1; //this will be helpful for the diagnostic
    while(csvFile.eof() == 0) {
        csvFile.getline(pStock,5,',');
        cout << "Iteration number " << i << endl;
        cout << *pStock<<endl;
        i++;
    }
    return 0;
}

我希望读取所有数字,因为假设 getline 会获取自上次读取以来写入的内容,并在遇到 ',' 或 '\n' 时停止。

但它似乎可以很好地读取所有内容,除了“4”,即第二行的第一个数字(参见控制台):

Iteration number 1
1
Iteration number 2
2
Iteration number 3
3
Iteration number 4
5
Iteration number 5
6

因此我的问题是:是什么让这个 '4' 在(我猜)'\n' 之后如此具体,以至于 getline 甚至没有尝试考虑它?

(谢谢!)

【问题讨论】:

    标签: c++ csv istream getline


    【解决方案1】:

    您正在读取逗号分隔的值,因此您按顺序读取:123\n456

    然后每次打印数组的第一个字符:即12356

    你期待什么?

    顺便说一句,您对eof 的检查放错了地方。您应该检查getline 调用是否成功。在您的特定情况下,它目前没有任何区别,因为 getline 读取某些内容并在一个操作中触发 EOF,但通常它可能会在不读取任何内容的情况下失败,并且您当前的循环仍会处理 pStock,就好像它已被重新填充一样成功。

    一般来说这样的东西会更好:

    while (csvFile.getline(pStock,5,',')) {
        cout << "Iteration number " << i << endl;
        cout << *pStock<<endl;
        i++;
    }
    

    【讨论】:

    • “你期待什么?”实际上,如果我看一下 cplusplus.com/reference/iostream/istream/getline ,在我看来 getline 与 '\n' 的作用就像它与指定的分隔符一样。即,在遇到它时停止读取(因此,就像“1,2”它在 2 之前停止,“3\n4”它应该在 4 之前停止)。但我想事实并非如此,我对一切都不太了解!谢谢你的回答。
    • @Kamixave:根据我对 cplusplus.com 的阅读,我不认为这是不正确的。 \n 只是默认分隔符(如果您不提供)。如果您确实提供了一个,则会使用它来代替(也不是)。
    • @Charles Bailey:您能否添加 std::getline(,) 示例。此版本可能会导致缓冲区溢出。
    • @Charles:是的,你是对的,我没有得到它的好方法。谢谢你:)
    • @Martin York:这个版本如何允许缓冲区溢出? (我知道有些幻数不是理想的做法,但我没有看到立即出现缓冲区溢出的危险。)
    【解决方案2】:

    AFAIK 如果您使用终止符参数,getline() 会一直读取直到找到分隔符。这意味着在您的情况下,它已阅读

    3\n4
    

    进入数组pSock,但你只打印第一个字符,所以你只得到3

    【讨论】:

      【解决方案3】:

      您的代码的问题是getline,当指定分隔符时,在您的情况下,','使用它并忽略默认分隔符'\ n'。如果要扫描该文件,可以使用标记化功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-05
        • 2020-07-23
        • 1970-01-01
        • 2014-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多