【问题标题】:C++ function `getline()` doesn't work correctly for char[]C++ 函数`getline()` 不能正确用于 char[]
【发布时间】:2020-12-16 18:08:59
【问题描述】:

我需要从一行中提取前 150 个字符并将它们保存在 char[] 数组中(不允许使用字符串)。我下面的代码不起作用,我只是找不到原因:

#include <ifstream>
#include <iostream>
using namespace std;
int main()
{
    ifstream myFile;
    myFile.open("message.txt");
    if(!myFile.is_open()) cout<<"error"; //added this after edit
    const int SIZE = 151;
    char buffer[SIZE]={};
    while(myFile.getline(buffer, 151)){
        buffer[150]='\0';
        cout<<buffer<<endl;
    }
    myFile.close();
}

这是“message.txt”的sn-p:

abcdefg
hijklmn
opqrstuv
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
hello

它只是什么也没打印出来。文件“message.txt”存在并且其中有几行字符。我哪里错了? 编辑:如果一行中的字符少于 150 个,则应全部读取。如果超过 150 个,则应忽略其余部分。

【问题讨论】:

  • 你知道文件打开成功了.. 如何 ?
  • 如果一行中的字符少于 150 个并且在读取的最后一个字符 getline 和您在位置 150 添加的空终止符之间有一堆未初始化的垃圾会发生什么?
  • 在这种情况下为什么要打扰char[]?我不会,除非它实际上需要成为一个缓冲区,比如以二进制模式读取。使用std::stringstd::getline() 会更轻松。
  • @sweenish char buffer[SIZE]={}; 零初始化所有元素。
  • 我无法重现此行为。我所做的只是将#include &lt;ifstream&gt; 更改为#include &lt;fstream&gt;(假设这是创建问题的错字并且实际代码编译!)并且它可以工作,包括示例message.txt

标签: c++ ifstream getline


【解决方案1】:

如果您尝试读取第一行的前 150 个字符,则不需要 while 循环。而且您不需要手动终止bufferistream::getline() 会为您执行此操作,例如:

#include <ifstream>
#include <iostream>
using namespace std;

int main()
{
    ifstream myFile("message.txt");
    if (!myFile.is_open())
    {
        cout << "error";
        return 0;
    }

    const int SIZE = 151;
    char buffer[SIZE] = {};
    myFile.getline(buffer, SIZE);

    cout << buffer << endl;

    myFile.close();
    return 0;
}

如果您只想读取特定行的前 150 个字符,那么您需要一个循环来跳过所有行无论它们的长度如何,直到达到所需的行,然后您可以读取该行的 150 个字符,例如:

#include <ifstream>
#include <iostream>
#include <limits>
using namespace std;

int main()
{
    ifstream myFile("message.txt");
    if (!myFile.is_open())
    {
        cout << "error";
        return 0;
    }

    size_t lineIndex = ...;
    while (lineIndex > 0)
    {
        if (!myFile.ignore(numeric_limits<streamsize>::max(), '\n'))
        {
            cout << "error";
            return 0;
        }

        if (myFile.eof())
        {
            cout << "eof";
            return 0;
        }

        --lineIndex;
    }

    const int SIZE = 151;
    char buffer[SIZE] = {};

    myFile.getline(buffer, SIZE);

    cout << buffer << endl;

    myFile.close();
    return 0;
}

如果您想读取每行的前 150 个字符,那么在成功读取后,您需要在换行之前跳过任何剩余的字符,然后才能读取下一行,例如:

#include <ifstream>
#include <iostream>
#include <limits>
using namespace std;

int main()
{
    ifstream myFile("message.txt");
    if (!myFile.is_open())
    {
        cout << "error";
        return 0;
    }

    const int SIZE = 151;
    char buffer[SIZE] = {};

    do
    {
        myFile.getline(buffer, SIZE);

        if (myFile.bad())
        {
            cout << "error";
            return 0;
        }

        if (myFile.fail())
        {
            // SIZE-1 characters were extracted before a line break
            // was reached, need to reset the error to keep going...
            myFile.clear();
            myFile.ignore(numeric_limits<streamsize>::max(), '\n');
        }

        cout << buffer << endl;
    }
    while (!myFile.eof());

    myFile.close();
    return 0;
}

【讨论】:

  • 太棒了!读取除最后一行之外的所有行,并排除第 150 行之后的所有字符。我们越来越近了!程序在最后一行之前停止的原因可能是什么?
  • @DanielHalachev 你自己说的 - 排除了第 150 位之后的所有字符。在您提供的文本文件中,如果使用 CRLF 换行符,hello 行从第 181 个字符开始,如果使用bare-CR 或bare-LF 换行符,则从第177 个字符开始。两者都远远超出了 150 个字符的限制。那么您期望会发生什么?
  • 哦,看来我还不够清楚。我希望程序从文件的 each 行中读取最多 150 个字符。很抱歉造成混乱。
  • @DanielHalachev 这与您最初发布的要求完全不同。我已经更新了我的答案
  • 非常感谢!我已经在这个问题上工作了一周,希望找到一个可以做到这一点的函数,我问了几个关于试图解决这个问题的问题。再次,非常感谢。痛苦终于过去了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
  • 2016-10-04
  • 1970-01-01
  • 2013-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多