【问题标题】:Reading text file into string array将文本文件读入字符串数组
【发布时间】:2017-09-12 02:34:18
【问题描述】:

我正在尝试将文件对象的内容读入字符串数组,但无论我尝试什么,当我打印数组的内容时都不会显示任何内容。具体来说,我想通过将文本文件的最后十行传递到数组中并在数组上使用 for 循环来打印它们。

void FileReader::displayLast10records(){

    ifstream ifile(filename);
    string myArray[26];

    cout << "\n" << filename << ":  LAST 10 records in file \n\n";

    for (int i = 0; i < numrecords; i++)
        getline(ifile, myArray[i]);

    ifile.close();

    if (numrecords < 10)
    {
        for (int i = 0; i < numrecords; i++)
            cout << setw(2) << (i + 1) << ".\t" << myArray[i] << endl;
    }
    else if (numrecords > 10)
    {
        for (int i = (numrecords - 10); i < numrecords; i++)
        {
            cout << setw(2) << (i + 1) << ".\t" << myArray[i] << endl;
        }
    }
}

文件只是大块的文本,包括空格。该文件如下所示:

编程语言是一种人工设计的语言 向机器传达指令,特别是 一台电脑。编程语言可用于创建 控制机器行为和/或 精确表达算法。 最早的编程语言早于发明 计算机,并被用来指导行为 提花织机和自动钢琴等机器。 已经有成千上万种不同的编程语言 主要是在计算机领域创建的,其中许多是 每年创建。大多数编程语言描述 命令式计算,即作为一个序列 命令,尽管某些语言,例如那些 支持函数式编程或逻辑编程,使用 其他形式的描述。

我想将每一行读入它自己的字符串数组元素中。

我确实有另一个函数成功地使用 getline() 一次显示文本文件的每一行 10 行。

void FileReader::displayAllRecords(){

ifstream ifile(filename);
int displayed_lines = 0;
string arec;

cout <<"\n" << filename << ": ALL records in the file with line numbers, 10 at a time \n\n";

while (getline(ifile, arec))
{
    if(displayed_lines % 10 == 0 && displayed_lines >= 1)
        system("pause");

    cout << setw(2) << (displayed_lines + 1) << ".\t" << arec << endl;
    displayed_lines++;
}


ifile.close();
}

【问题讨论】:

  • 您以哪种格式将数据存储在文件中?
  • 哦,对了。文件的每一行都是包含空格的文本行。类似于:编程语言是一种人工语言,旨在将指令传达给机器,尤其是计算机。编程语言可用于创建控制机器行为和/或精确表达算法的程序。
  • 我不认为以下是错误,但您打开文件两次。首先使用构造函数 ifstream ifile(filename);其次使用函数 ifile.open(filename);.
  • 好的。谢谢,我会解决的。
  • 似乎是启动调试器的理想方案

标签: c++ arrays string file getline


【解决方案1】:

通常这是您可以使用ifstream 读取行的方式:

#include <fstream>
#include <string>
#include <list>

using namespace std;

void readFile(const char* filename, list<string>& lines)
{
    lines.clear();
    ifstream file(filename);
    string s;
    while (getline(file, s))
        lines.push_back(s);
}

或阅读最后 10 行:

void readLast10(const char* filename, list<string>& lines)
{
    lines.clear();
    ifstream file(filename);
    string s;
    while (getline(file, s))
    {
        lines.push_back(s);
        if (line.size() > 10)
            lines.pop_front();
    }
}

然后你可以打印最后 10 行:

int main()
{
    list<string> lines;
    readFile(filename, lines);
    int n = 0;
    printf("read %d lines\n", lines.size());
    for (auto const it=lines.rbegin(); it!=lines.rend() && n<10; ++it, ++n)
        printf("line%2u:\t%s\n", lines.size()-n, it->c_str());
}

或类似:

int main()
{
    list<string> lines;
    readLast10(filename, lines);
    int n = 0;
    cout << "read " << lines.size() << endl;
    for (const auto& line : lines)
        cout << l << endl;
}

请注意,getline 逐行读取,也就是说,如果您的文本不包含换行符,您的整个文件将被读取,就好像它只是一个文件一样。

【讨论】:

  • 好的,谢谢。那么,如果文件本身没有换行符,我不能只将每一行读入一个常规数组吗?
  • @johnbodhi 如果没有换行符,您就没有行,而只有一个很长的行。
  • 我明白了。我在这里确实有另一个功能,尽管使用 getline 成功地一次显示每行 10 行。我不知道如何在这些 cmets 中显示。
  • 您可以编辑原始问题并将其添加到那里。
  • 不确定我做了什么,但它现在可以工作了!哈哈。根据每个人的建议,我将了解更多关于未来列表的信息。谢谢。
【解决方案2】:

您的文件可能没有像您的程序所期望的那样包含正确的行结束标记,但您的代码假设该文件刚刚得到numrecords 行结束标记。该变量在哪里定义以及如何获得它是另一个问题。 这里不要使用静态数组,使用std::list,使用list::reverse_iterator(可以从list::rbegin()获取值,迭代10次,除非迭代器变得等于list::rend())来遍历最后10条记录,你的代码会简单得多(实际上,只有几行)

【讨论】:

  • 谢谢。我对列表还不是很熟悉,但我会看看我能做什么。 numrecords 是一个私有成员变量,一旦文件的每一行在另一个成员函数中被读取,就会被定义。
猜你喜欢
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多