C++:解析和读取文本文件到数组

问题描述:

我希望能在这里找到一些帮助。我下周要完成一项任务,包括从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

您可以使用矢量数据结构来保存书类。 矢量记录;

也许你只需要知道如何处理字符串中的每个字符?

下面是一些代码,通过构建单词的字符串的每个字符,然后单独打印它们。您会注意到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

(我强烈建议使用一个载体(或清单),因为它会避免文件的双重阅读,因为你不需要知道行号都没有。)

要解析有场固定数量的一条线,很容易原则:

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