getstream()与ifstream的意外行为

时间:2010-08-18 10:31:30

标签: c++ csv istream getline

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

(谢谢!)

3 个答案:

答案 0 :(得分:6)

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

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

你在期待什么?

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

更普遍这样的事情会更好:

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

答案 1 :(得分:3)

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

3\n4

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

答案 2 :(得分:1)

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