getline似乎工作不正常

getline seems to not working correctly

本文关键字:不正常 工作 getline      更新时间:2023-10-16

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

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

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

  char num[4][15];

我想我正在做的是:只要你没有到达文件的末尾,就把每一行(最多15个字符,以'\n'结尾)都写进num行。但这在某种程度上不起作用。首先,它只正确读取第一个数字,其余的只是"(空字符串),其次,file.of()似乎也不能正常工作。在我下面展示的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
222222222222
333333333333333
444444444444

p.S.
我使用的是VS2010 sp1

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

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

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

由于设置了故障位,因此进一步尝试调用file.getline()不起任何作用。

!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 ''
    for (unsigned lines = 0;
         lines < 4 && file.getline(numbers[lines], 16);
         ++lines)
    {
        std::cout << "numbers[" << lines << "] = " << numbers[lines] << 'n';
    }
}

在Visual Studio 2010 SP1 上测试

根据ifstream文档,读取n-1个字符或找到delim符号后,读取就会停止:第一次读取只需要14个字节。

它读取字节:"1"(字符)是0x41:您的缓冲区将填充0x41,而不是您所期望的1,最后一个字符将是0(c字符串的末尾)

附带说明,您的代码不会检查行是否超出您的数组。

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

第一个类末尾的'\n'似乎没有被考虑,而是保留在缓冲区中。所以在下一个getline()中,它被读取。

尝试在每个getline()之后添加一个文件.get()。

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

结尾

将其更改为以下内容:

#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] = '';
        }
    }
}