2013-04-22 284 views
0

我希望能在這裏找到一些幫助。我下週要完成一項任務,包括從txt文件中讀取一堆數據到數組中,然後打印出結果。的數據是在以下格式:C++:解析和讀取文本文件到數組

「麥克白」, 「莎士比亞」, 「41.04」, 「161」, 「23」, 「978-88-5985-004-5」

「A聖誕頌歌「,」查爾斯狄更斯「,」98.74「,」167「,」547「,」978-26-2885-780-7「。 。

每一行都有六條信息,我需要存儲以供以後使用。我應該編寫代碼來計算我們擁有的文本行數,以便創建正確大小的動態數組。我已經覆蓋了。我有39行條目。然後我應該創建一個讀取txt文件的函數,並將所有數據保存到我創建的數組中的相應對象。

我不知道使用什麼方法,並且我一直在四處尋找教程和解釋幾天。我對文件和解析的經驗非常有限,所以如果我有點經驗不足,請原諒。這裏是我到目前爲止的代碼:

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

using namespace std; 


class Author 
{ 
    public: 

private: 
    string fname, lname; 

}; 

class Book 
{ 
    friend ofstream& operator<<(ofstream&, Book); 

     public: 
     Book(); 

    private: 
     string bookName; 
     Author author; 
     double price; 
     int qtyOnHand; 
     int qtySold; 
     double revenue; 
     string ISBN; 

}; 

Book :: Book() 
{ 

} 

int getLineNumber(ifstream &); 
void parseData(ifstream &, Book []); 


//void sortBookList(Book[], int, int); 


int main() 
{ 
    int numberOfBooks; 

    //open the file from which to read the data 
    ifstream myFile; 
    myFile.open("Book List.txt"); 
    //function to find out how many objects to create 
    numberOfBooks = getLineNumber(myFile); 

    //create an array with that many objects 
    Book *bptr; 
    bptr = new Book[numberOfBooks]; 
    //function to read information from file into array of objects 
    parseData(myFile, bptr); 

    //loop to call sorting function and output function based on 4 different criteria 

    //close the file explicitly 
    return 0; 
} 

int getLineNumber(ifstream &myFile) 
{ 
    int counter = 0; 
    string myString; 


    while(!myFile.eof()) 
    { 
     getline(myFile, myString); 
     counter++; 
    } 

    myFile.close(); 

    counter --; 
    return counter; 
} 

void parseData(ifstream &myFile, Book bookPtr[]) 
{ 

} 

所以,總結一下我的問題,我不明白如何從文本文件中的數據解析到我的數組。 非常感謝您提前幫助任何人!乾杯。

編輯:我試過與代碼搞混了,我想我在正確的方向邁出了一步,但我仍然有點迷路。這是我對parseData函數的看法。

void parseData(ifstream &myFile, Book bookPtr[]) 
{ 

    string dummyLine; 

    string word, line; 
    myFile.open("Book List.txt"); 
    getline(myFile, dummyLine); 
    string data[6]; 

    while(!myFile.eof()) 
    { 
     getline(myFile, line, '\n'); 

     for (size_t i = 0; i < line.size(); ++i) 
     { 
      char c = line[i]; 

      if(c == ',' || c == '\n') 
      { 
       if(!word.empty()) 
       { 
        data[i] = word; 
        word.clear(); 
       } 
      } 
      else 
      { 
       word += c; 
      } 


     } 
     if(!word.empty()) 
     { 
      //cout << word << endl; 
     } 
    } 




} 
+0

你在尋找什麼樣的功能? 'getline()'很有用,但你已經在使用它了。你似乎也已經知道如何使用字符串。你還需要什麼? – 2013-04-22 22:44:36

+0

這個新代碼不起作用? – 2013-04-23 19:10:38

回答

0

您可以使用矢量數據結構來保存書類。 矢量記錄;

2

也許你只需要知道如何處理字符串中的每個字符?

下面是一些代碼,通過構建單詞的字符串的每個字符,然後單獨打印它們。您會注意到stringvectorstr[i]str.push_back(char)str.size()等)具有相同的接口。

// You'll need to include <iostream> and <string> 

std::string example = "This is an example string"; 
std::string word; 

// Notice how you can loop through a string just like a vector<char> 
for(size_t i = 0; i < example.size(); ++i) { 
    char c = example[i]; 

    // When we see whitespace, print the current word and clear it 
    if(c == ' ' || c == '\t' || c == '\n') { 
     // Don't print anything if we don't have a word 
     if(!word.empty()) { 
      std::cout << word << std::endl; 
      word.clear(); 
     } 
    } else { 
     // Append the current character to the end of the string 
     word += c; // or word.push_back(c) 
    } 
} 
// In case the line doesn't end with whitespace 
if(!word.empty()) { 
    std::cout << word << std::endl; 
} 

std::basic_string (alias for std::string) reference可能是有用的。

+0

這有助於很多!我會嘗試將這個用於我的程序。非常感謝。 – Sam 2013-04-22 23:21:17

+0

我試圖搞亂它,但無濟於事。你能否在正確的方向給我另一個指針(沒有編程雙關語)? 我在更新的代碼的原始帖子中發佈了一個修改。 – Sam 2013-04-23 03:12:02

0

(我強烈建議使用一個載體(或清單),因爲它會避免文件的雙重閱讀,因爲你不需要知道行號都沒有。)

要解析有場固定數量的一條線,很容易原則:

int counter = 0; 
string myString; 


while(!myFile.eof()) 
{ 
    getline(myFile, myString); 
    counter++; 
} 
counter --; 

//Clear the error state flag 
myFile.clear() 

//Return to the beginning of the file: 
myFile.seekg(ios_base::beg); 


const int fieldCount = 5; 
string field[fieldCount ]; 


string buffer= ""; 
char c = '\0'; 
for(int i = 0; i < counter; ++i) { 
    for(int j = 0; j < fieldCount; ++j) { 
     myFile.ignore(); //Ignore the first '"' 
     //Read each character up to the second '"' 
     while(myFile.good() && (c = myfile.get()) != '"') { 
      buffer += c; 
     } 
     field[j] = buffer; 
     buffer = ""; 
     if(j != fieldCount - 1) { 
      myFile.ignore(); //Ignore the first ',' 
     } 
    } 

    //Use the fields here. 

} 

我沒有測試此代碼,我知道有一個缺乏差錯測試的,但它顯示了一個辦法做到這一點。

+0

你也可以在第二個for循環中添加一個字段特定的方法來用swith(j)解析它,這樣你就可以解析一個int(即int x; myFile >> x;)而不是一個字符串。 – fstamour 2013-04-23 01:03:33