簡體   English   中英

C ++文本文件轉換為多維數組問題

[英]C++ text file into multi-dimensional array problems

作為學校項目的一部分,我想將清單* .txt文件放入C ++數組中,並最終在程序的后面部分返回到* .txt文件。

文本文件將以10行開始,這些行將代表雜貨店的故事商品,並將包括三列,分別代表商品的名稱,價格和數量。 我已經能夠從文件中讀取信息,甚至可以在顯示的每一行前面添加數字。 現在,我想將文本文件放入一個字符串數組中,以便“雇員”用戶可以一次更改一項,然后將其轉儲到* .txt文件中。

到目前為止,我一直在嘗試以下代碼。 我可以獲取文件中的行數,但似乎無法計算出列數或顯示的行中的數據。 當我運行該程序時,在顯示行(10)和Cols(0)之后,我得到的似乎是10條空行。

* .txt文件中的列通常用空格分隔。 我嘗試了一個選項卡,然后嘗試了: while(getline(invFile, lines, '\\t');只是使控制台顯示了我猜測的內存地址,然后崩潰了。

不幸的是,我們還沒有深入調試程序,從提綱的角度來看,我認為不會很全面地介紹它,因此我不知道如何進一步解決問題。 我在Google-ing的最后幾個小時中花了很多時間,但實際上我需要尋求幫助。

該項目涉及的內容遠遠超過此部分,但我確實停留在這一部分。 我並不是要有人為我做這件事,但是如果有人知道我在做什么錯,並可以指出將文本文件轉換成多維數組的最佳方向,我將不勝感激。

謝謝。

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

您可以通過幾種方法來做到這一點。 最簡單的方法是在文件頂部放置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);
}

第二種方法的好處是雙重的。 首先,這很容易。 我猜您可能不知道它是如何工作的,但是Google可以通過一些簡單的Google搜索來搜索您不知道的關鍵字,並且您會很快找到它。 第二個是(理論上)它允許無限的行和不受限制的列。 那樣的話,我的意思是一行可以有20列,一行可以有2列,並且不會浪費空間。

請注意,在研究之前,請勿使用我顯示的框架代碼。 如果您至少對這里發生的事情沒有一個大致的了解,那么稍后您會為自己帶來問題。 我不會在這里解釋所有內容,因為其他人已經做到了。 另外,由於您是在學校學習的,因此最終您將獲得這些東西,因此您將不斷前進。 一個主要的約束是如果您的項目需要數組,在這種情況下,我的第一個解決方案將是最佳選擇。

我想建議您在重要步驟中添加一些打印行-我認為這也是一種快速且良好的“調試”方法。 這樣您就可以輕松找到錯誤的地方。 例如,在您的代碼中,似乎未分配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的值為Applesoperator <<將返回NULL,這是不合理的,將Apples設置為int ,到目前為止,找到了第1點。如果必須使用intfloat以存儲數字,請使用一些轉換API,例如atoiatof

xint更改為string ,分割變得毫無意義,顯然textArray [2] [2]不足以存儲所有信息。 “超出范圍”是分段錯誤的原因,因此請對大型陣列進行測試直到通過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM