getline似乎无法正常工作

时间:2011-06-08 17:53:44

标签: c++ fstream getline

请告诉我这里我做错了什么。我想做的是这个:
1.带有四个数字的txt文件,每个数字都有15位数字:

std::ifstream file("numbers.txt",std::ios::binary);

我正在尝试将这些数字读入我的数组:

  char num[4][15];

而我正在想的是:只要你没有到达文件的末尾就会将每行(最多15个字符,以'\ n'结尾)写入num [lines]。但这有点不起作用。首先它只读取第一个数字,rest只是“”(空字符串),其次file.eof()似乎也无法正常工作。在我在下面这段代码中提出的txt文件中,我达到了等于156的行。发生了什么事?

                for (unsigned lines = 0; !file.eof(); ++lines)
                {
                    file.getline(num[lines],15,'\n');  
                }

所以整个“例程”看起来像这样:

int main()
{
std::ifstream file("numbers.txt",std::ios::binary);

char numbers[4][15];

            for (unsigned lines = 0; !file.eof(); ++lines)
            {
                file.getline(numbers[lines],15,'\n');// sizeof(numbers[0])
            }
}

这是我的txt文件的内容:

111111111111111
222222222222222个
333333333333333个
444444444444444

P.S。
我正在使用VS2010 sp1

5 个答案:

答案 0 :(得分:6)

不要使用eof()函数!读取行的规范方法是:

while( getline( cin, line ) ) {
    // do something with line
}

答案 1 :(得分:1)

file.getline()提取14个字符,填写num[0][0] .. num[0][13]。然后它会在'\0'中存储num[0][14]并在failbit上设置file,因为这是缓冲区已满但终止未到达字符时的操作。

进一步尝试调用file.getline()无效,因为设置了failbit。

!file.eof()的测试返回true,因为未设置eofbit。

编辑:给出一个有效的例子,当然最好是使用字符串,但要填写你的char数组,你可以这样做:

#include <iostream>
#include <fstream>
int main()
{
    std::ifstream file("numbers.txt"); // not binary!
    char numbers[4][16]={}; // 16 to fit 15 chars and the '\0'
    for (unsigned lines = 0;
         lines < 4 && file.getline(numbers[lines], 16);
         ++lines)
    {
        std::cout << "numbers[" << lines << "] = " << numbers[lines] << '\n';
    }
}

在Visual Studio 2010 SP1上测试

答案 2 :(得分:1)

根据ifstream doc,读取n-1个字符或找到delim符号后停止读取:首先读取只需14个字节。

它读取字节:'1'(字符)是0x41:你的缓冲区将填充0x41而不是1,如你所料,最后一个字符将为0(c-string结尾)

旁注,您的代码不会检查线条是否超出您的数组。

使用getline假设您期望文本并以二进制模式打开文件:对我来说似乎不对。

答案 3 :(得分:0)

将其更改为以下内容:

#include <cstring>

int main()
{
    //no need to use std::ios_base::binary since it's ASCII data
    std::ifstream file("numbers.txt");

    //allocate one more position in array for the NULL terminator
    char numbers[4][16];

    //you only have 4 lines, so don't use EOF since that will cause an extra read
    //which will then cause and extra loop, causing undefined behavior
    for (unsigned lines = 0; lines < 4; ++lines)
    {
        //copy into your buffer that also includes space for a terminating null
        //placing in if-statement checks for the failbit of ifstream
        if (!file.getline(numbers[lines], 16,'\n'))
        {
            //make sure to place a terminating NULL in empty string
            //since the read failed
            numbers[lines][0] = '\0';
        }
    }

}

答案 4 :(得分:0)

看起来第一个结尾的'\ n'没有被考虑,并保留在缓冲区中。因此,在下一个getline()中,它会被阅读。

尝试在每个getline()之后添加file.get()。

如果一个file.get()不起作用,请尝试两个,因为在Windows默认文件编码下,该行以'\ n \ r \'(或'\ r \ n''结尾,我永远不知道:) / p>