getline() 与 ifstream 的意外行为

发布于 2024-09-14 20:02:56 字数 1113 浏览 11 评论 0原文

为了简化,我尝试使用 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 甚至没有尝试考虑它?

(谢谢 !)

To simplify, I'm trying to read the content of a CSV-file using the ifstream class and its getline() member function. Here is this CSV-file:

1,2,3
4,5,6

And the code:

#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;
}

I'm expecting all the numbers to be read, since getline is suppose to take what is written since the last reading, and to stop when encountering ',' or '\n'.

But it appears that it reads everything well, EXCEPT '4', i.e. the first number of the second line (cf. console):

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

Thus my question: what makes this '4' after (I guess) the '\n' so specific that getline doesn't even try to take it into account ?

(Thank you !)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝梦月影 2024-09-21 20:02:56

您正在读取逗号分隔的值,因此按顺序读取: 1, 2, 3\n4, 5, <代码>6。

然后,每次打印数组的第一个字符:即 1235、<代码>6。

你在期待什么?

顺便说一句,您对 eof 的检查位置错误。您应该检查 getline 调用是否成功。在您的特定情况下,它目前不会产生任何影响,因为 getline 会在一个操作中读取某些内容并触发 EOF,但一般来说,它可能会在不读取任何内容的情况下失败,并且您当前的循环仍会处理 pStock 就像它已成功重新填充一样。

更一般地说,像这样的东西会更好:

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

You are reading comma separated values so in sequence you read: 1, 2, 3\n4, 5, 6.

You then print the first character of the array each time: i.e. 1, 2, 3, 5, 6.

What were you expecting?

Incidentally, your check for eof is in the wrong place. You should check whether the getline call succeeds. In your particular case it doesn't currently make a difference because getline reads something and triggers EOF all in one action but in general it might fail without reading anything and your current loop would still process pStock as if it had been repopulated successfully.

More generally something like this would be better:

while (csvFile.getline(pStock,5,',')) {
    cout << "Iteration number " << i << endl;
    cout << *pStock<<endl;
    i++;
}
始终不够爱げ你 2024-09-21 20:02:56

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

3\n4

入数组 pSock,但您只打印第一个字符,因此您只得到 3

AFAIK if you use the terminator parameter, getline() reads until it finds the delimiter. Which means that in your case, it has read

3\n4

into the array pSock, but you only print the first character, so you get 3 only.

薄暮涼年 2024-09-21 20:02:56

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

the problem with your code is that getline, when a delimiter is specified, ',' in your case, uses it and ignores the default delimiter '\n'. If you want to scan that file, you can use a tokenization function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文