getline 似乎无法正常工作

发布于 2024-11-14 16:05:56 字数 1011 浏览 4 评论 0原文

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

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

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

  char num[4][15];

我想我正在做的是:只要你没有达到文件末尾将每一行(最多 15 个字符,以 '\n' 结尾)写入 num[lines]。但这有点行不通。首先,它仅正确读取第一个数字,其余部分只是“”(空字符串),其次 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

附注
我用的是VS2010 sp1

Please tell me what am I doing wrong here. What I want to do is this:
1.Having txt file with four numbers and each of this numbers has 15 digits:

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

I'm trying to read those numbers into my array:

  char num[4][15];

And what I'm thinking I'm doing is: for as long as you don't reach end of files write every line (max 15 chars, ending at '\n') into num[lines]. But this somewhat doesn't work. Firstly it reads correctly only first number, rest is just "" (empty string) and secondly file.eof() doesn't seems to work correctly either. In txt file which I'm presenting below this code I reached lines equal 156. What's going on?

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

So the whole "routine" looks like this:

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])
            }
}

This is contents of my txt file:

111111111111111
222222222222222
333333333333333
444444444444444

P.S.
I'm using VS2010 sp1

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

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

发布评论

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

评论(5

魂ガ小子 2024-11-21 16:05:56

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

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

Do not use the eof() function! The canonical way to read lines is:

while( getline( cin, line ) ) {
    // do something with line
}
泡沫很甜 2024-11-21 16:05:56

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

进一步尝试调用 file.getline() 不会执行任何操作,因为设置了失败位。

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

编辑:给出一个工作示例,当然最好是使用字符串,但是要填充字符数组,您可以这样做:

#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 上测试

file.getline() extracts 14 characters, filling in num[0][0] .. num[0][13]. Then it stores a '\0' in num[0][14] and sets the failbit on file because that's what it does when the buffer is full but terminating character not reached.

Further attempts to call file.getline() do nothing because failbit is set.

Tests for !file.eof() return true because the eofbit is not set.

Edit: to give a working example, best is to use strings, of course, but to fill in your char array, you could do this:

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

tested on Visual Studio 2010 SP1

如果没结果 2024-11-21 16:05:56

根据 ifstream doc,读取在读取 n-1 个字符后停止,或者发现 delim 符号:第一次读取只需要 14 个字节。

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

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

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

According to ifstream doc, reading stops either after n-1 characters are read or delim sign is found : first read would take then only 14 bytes.

It reads bytes : '1' (the character) is 0x41 : your buffer would be filled with 0x41 instead of 1 as you seem to expect, last character will be 0 (end of c-string)

Side note, your code doesn't check that lines doesn't go beyond your array.

Using getline supposes you're expecting text and you open the file in binary mode : seems wrong to me.

千鲤 2024-11-21 16:05:56

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

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

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

It looks like the '\n' in the end of the first like is not being considered, and remaining in the buffer. So in the next getline() it gets read.

Try adding a file.get() after each getline().

If one file.get() does not work, try two, because under the Windows default file encoding the line ends with '\n\r\' (or '\r\n', I never know :)

掩于岁月 2024-11-21 16:05:56

将其更改为以下内容:

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

}

Change it to the following:

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

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