C++文本文件成多维数组问题

C++ text file into multi-dimensional array problems

本文关键字:数组 问题 文本 文件 C++      更新时间:2023-10-16

作为学校项目的一部分,我想在C++中将库存 *.txt 文件放入数组中,并最终在程序的后面部分返回到 *.txt 文件。

文本文件将以 10 行开头,这些行将表示杂货店故事项目,并将包括三列表示项目的名称、价格和数量。 我已经能够从文件中读取,甚至在显示的每一行前面添加数字。 现在,我想将文本文件放入字符串数组中,以便"员工"用户可以一次更改一个项目,然后我可以将该数组转储回 *.txt 文件中。

下面的代码是我到目前为止一直在尝试的代码。 我可以获取文件中的行数,但似乎无法计算列数或显示行中的数据。 当我运行程序时,在显示行 (10) 和 Cols(0) 后,我得到似乎是 10 个空行。

*.txt 文件中的列通常用空格分隔。 我尝试了一个选项卡,并尝试了:while(getline(invFile, lines, 't');它只是导致控制台显示我猜测的内存地址,然后崩溃。

不幸的是,我们还没有深入调试程序,从教学大纲的角度来看,我认为不会非常彻底地涵盖,所以我不知道如何进一步排除故障。 在过去的几个小时里,我花了几个小时在谷歌上搜索,并且已经到了我实际上需要寻求帮助的地步。

该项目涉及的不仅仅是这个组件,但我真的被困在这一部分。我不是要求有人为我做这件事,但如果有人知道我做错了什么,并且可以指出我将文本文件放入多维数组的最佳方向,我将不胜感激。

谢谢。

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string>
    #include <sstream>
    #include <array>

    int row = 0;
    int col = 0;
    using namespace std;
    int main()
    {
        string lines;
        int x;
        string textArray[2][2];
        ifstream invFile;
        invFile.open("inventory.txt");
        if(invFile.fail()){
            cerr << "The file cannot be opened!";
            exit(1);
        }
        cout << "n" << endl;
        while(invFile.good()) {
            while(getline(invFile, lines)) {
                istringstream streamA(lines);
                col = 0;
                while(streamA >> x) {
                    cout << x;
                    textArray[row][col] = x;
                    col++;
                }
                row++;
            }
        }
        invFile.close();
        cout << "Rows: " << row << endl;
        cout << "Cols: " << col << endl;
        cout << "n" << endl;
        for(int i=0; i<row; i++){
            for(int j=0; j<col; j++){
                cout << "Line: " << i << textArray[i][j] << ".";
            }
            cout << "n";
        }
        return(0);
    }
=============================
    inventory.txt:
    Apples 1.25 20
    Oranges 1.75 20
    Kiwi 2.50 15
    Pineapples 5.50 20
    Tomatoes 1.50 20
    Onions 2.00 20
    Corn 1.80 20
    Carrots 2.30 20
    Milk 4.50 20
    Cheese 2.25 20

我建议您创建一个structclass来保存数据。从每行文本中,适当地提取字段并将其提取到您的struct。然后,使用 std::vector 保留这些struct的列表。

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <array>
#include <vector>
#include <cstdlib>
using namespace std;
struct Row
{
   vector<string> columns;
};
int main()
{
   string line;
   vector<Row> rows;
   ifstream invFile;
   invFile.open("inventory.txt");
   if(invFile.fail()){
       cerr << "The file cannot be opened!";
       exit(1);
   }
   cout << "n" << endl;
   while(invFile.good()) {
       while(getline(invFile, line)) 
       {
          Row row;
          istringstream streamA(line);
          string col;
          while ( streamA >> col )
          {
             row.columns.push_back(col);
          }
          rows.push_back(row);
       }
   }
   invFile.close();
   cout << "Rows: " << rows.size() << endl;
   cout << "Cols: " << rows[0].columns.size() << endl;
   cout << "n" << endl;
   for(int i=0; i<rows.size(); i++){
       for(int j=0; j<rows[i].columns.size(); j++){
           cout << "Line: " << i << " " << rows[i].columns[j] << "n";
       }
       cout << "n";
   }
   return(0);
}

我想建议你在重要步骤中添加一些打印行——我认为这也是一种快速且良好的"调试"方法。这样你可以很容易地找到你错的地方。例如,在您的代码中,似乎没有分配textArray,因此请在附近添加一些打印:

while(getline(invFile, lines)) {
                cout <<"lines: " << lines << endl; //test enter here
                istringstream streamA(lines);
                col = 0;
                while(streamA >> x) {
                    cout << "x is" << x; //test if enter here
                    textArray[row][col] = x;
                    col++;
                }
                row++;
            }

通过输出,行正常,但cout << "x is" << x;没有打印,这意味着while(streamA >>x)条件为假,为什么?

去找一个叫做 std::istringstream 的库函数,x 是 int 类型,但 col 1 值是 Apples 的,operator <<会返回 NULL,这是不合理的断言Apples到一个int,直到现在,找到了第 1 点。如果必须使用intfloat来存储数字,请使用一些转换API,如atoiatof

int更改为string x后,得到了分割法鲁特,显然textArray[2][2]不足以存储所有信息。"超出范围"是分段错误的原因,所以做一个大数组继续测试,直到通过。

几种方法可以做到这一点。最简单的方法是在文件的顶部放置类似 3,10 的内容,然后您就知道三列和 10 行。由于您在修改后编写此内容,因此您只需要确保这些数字正确写入即可。

如果你想学习一些更高级的方法,那么在你学习更多之后,你的生活会更轻松。

如果你使用向量,使用类似vector< vector<string> >的东西,你可以读到一个stringstream,然后拆分行读取并将其放入向量中

fstream file(...);
string tempString;
vector< vector<string> > list;
// Get a full line
while(getline(file, tempString, 'n'){
    // Create a StringStream and store tempString in it for further manipulation
    stringstream ss;
    ss << tempString;
    vector<string> tempVec;
    // Get each column from this row
    while(getline(ss, tempString, 't'){
        // Put each column into a vector
        tempVec.push_back(tempString);
    }
    // Put the entire vector into our list vector
    list.push_back(tempVec);
}

第二种方法的好处是双重的。首先,这很容易。我猜你不知道它是如何工作的,但是一些简单的谷歌搜索你不知道的关键词,你会很快发现。第二个是它允许(理论上)无限行和不受约束的列。我的意思是一行可以有 20 列,一行可以有 2 列,并且不会浪费空间。

请注意,在研究之前,您不应该使用我展示的骨架代码。如果你对这里发生的事情没有一个大致的了解,那么你以后只会给自己带来麻烦。我不会在这里解释所有内容,因为其他人已经这样做了。此外,由于你在学校学习了这一点,你最终会接触到这些东西,所以你只会领先。一个主要限制是,如果您的项目需要数组,在这种情况下,我的第一个解决方案将是最佳选择。