【问题标题】:C++: Parsing and Reading Text File Into an ArrayC++:解析文本文件并将其读入数组
【发布时间】:2013-04-23 11:13:43
【问题描述】:

我希望我能在这里找到一些帮助。我有一个下周到期的作业,涉及从 txt 文件中读取一堆数据到一个数组中,然后打印出结果。数据格式如下:

"麦克白","威廉莎士比亚","41.04","161","23","978-88-5985-004-5"

“圣诞颂歌”、“查尔斯狄更斯”、“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;
        }
    }




}

【问题讨论】:

  • 您在寻找什么样的功能? getline() 很有用,但您已经在使用它了。您似乎也已经知道如何使用字符串。你还需要什么?
  • 这个新代码有什么问题?

标签: c++ file parsing


【解决方案1】:

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

这里有一些代码遍历字符串的每个字符来构建单词,然后单独打印它们。您会注意到stringvector 具有相同的接口(@98​​7654324@、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 可能很有用。

【讨论】:

  • 这很有帮助!我会尝试将它用于我的程序。非常感谢。
  • 我试着弄乱它,但无济于事。你能在正确的方向上给我另一个指针(不是编程双关语)吗?我在更新代码的原始帖子中发布了一个编辑。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    (我强烈建议为此使用向量(或列表),因为它可以避免重复读取文件,因为您根本不需要知道行数。)

    要解析具有固定数量字段的行,原则上很容易:

    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.
    
    }
    

    我没有测试此代码,我知道缺少错误测试,但它显示了一种方法。

    【讨论】:

    • 您还可以在第二个 for 循环中添加一个特定于字段的方式来使用 swith(j) 解析它,这样您就可以解析一个 int (即 int x; myFile >> x; ) 而不是字符串。
    猜你喜欢
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 2021-12-12
    相关资源
    最近更新 更多