2014-03-31 48 views
0

作爲一個學校項目的一部分,我希望將庫存* .txt文件轉換爲C++數組,並最終返回到* .txt文件中程序。將C++文本文件轉換爲多維數組問題

該文本文件將以10行代表雜貨故事項目開始,並將包括代表項目名稱,價格和數量的三列。我已經能夠從文件中讀取數據,甚至可以在顯示的每行前添加數字。現在,我希望將文本文件轉換爲字符串數組,以便「員工」用戶可以逐個更改項目,然後將該數組轉儲回* .txt文件。

下面的代碼是我到目前爲止一直在嘗試的。我可以獲取文件中的行數,但似乎無法獲得列數或顯示行中的數據。當我運行程序時,在顯示行(10)和列(0)後,我看到10行空行。

* .txt文件中的列通常由空格分隔。我嘗試了一個標籤,並試圖:while(getline(invFile, lines, '\t');,這只是導致控制檯顯示我猜測的內存地址,然後崩潰。

不幸的是,我們還沒有深入到調試程序,從教學大綱的角度來看,我不認爲這將會被徹底地覆蓋,所以我不知道如何排除故障。我已經花了幾個小時的時間Google,並且已經到了需要求助的地步。

該項目涉及到很多比這個組件,但我真的被困在這一部分。我不是要求某人爲我做這件事,但如果任何人有任何想法我做錯了什麼,並可以指向我將文本文件轉換爲多維數組的最佳方向,我將非常感激。

謝謝。

#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 
+1

我可以看到兩個問題。第一個是變量'x'的類型。它應該是一個'string',因爲例如「Oranges」不能被解析爲一個數字,並且會導致while(streamA >> x)'在第一次嘗試時失敗。第二個問題是'textArray'的聲明。數組邊界都不足以存儲您擁有的數據。使用'textArray [20] [3]'應該可以工作,但是你應該嘗試理解爲什麼。 – msandiford

+0

我看到你的第二句話以後,我的耳朵會打傷幾個小時!我盯着這幾個小時,除了x的數據類型外,其他所有的東西都改變了。我忘記了我用一個整數列表開始,然後更改爲字符串。在之前的測試中,我的陣列尺寸較大。一旦我將它們都移回到10並將x更改爲字符串,則一切都很完美。非常感謝! – jayvee

回答

1

我想建議你添加的重要一步一些打印行 - 我認爲這也是一個快速&好「調試」的方法。以便您可以輕鬆找到您錯誤的地方。 例如,在你的代碼,似乎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::istringstreamx爲int類型,但第1個欄值Applesoperator <<將返回NULL,這是不合理的assing Applesint,到現在,發現點1.如果必須使用intfloat來存儲號碼,使用一些轉換API,如atoi,atof

更改後xintstring,得到分割失敗,顯然textArray [2] [2]是不足以存儲所有的信息。 「超出範圍」是分段錯誤的原因,因此建立一個大數組繼續測試直至通過。

1

有幾種方法可以做到這一點。最簡單的方法是在文件頂部放置3,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列,並且沒有浪費的空間。

請注意,在研究之前,您不應該使用我顯示的框架代碼。如果你對這裏發生的事情一無所知,那麼你以後就會爲自己造成問題。我不會在這裏解釋一切,因爲其他人已經這樣做了。另外,因爲你在學校學習,你最終會得到這些東西,所以你就會領先。如果您的項目需要陣列,則主要的約束條件是,在這種情況下,我的第一個解決方案將是最佳選擇。

+0

我們最近覆蓋了矢量,我只是對它們不太舒服。我想我會試一試,因爲這將是一個很好的做法。謝謝。 – jayvee

3

我建議你創建一個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); 
} 
+0

我們正在儘快瞭解這些情況,並從我所看到的情況看,他們應該更好地工作。不幸的是,我必須堅持我們迄今爲止所報道的內容。謝謝。 – jayvee