0

ここで何か助けが得られることを願っていました。来週、txt ファイルから一連のデータを配列に読み取り、結果を出力する課題があります。データの形式は次のとおりです。

"マクベス"、"ウィリアム シェイクスピア"、"41.04"、"161"、"23"、"978-88-5985-004-5"

「クリスマス キャロル」、「チャールズ ディケンズ」、「98.74」、「167」、「547」、「978-26-2885-780-7」。.

.

.

各行には、後で使用するために保存する必要がある 6 つの情報があります。正しいサイズの動的配列を作成するために、テキストの行数をカウントするコードを書くことになっています。私はそれをカバーしました。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;
        }
    }




}
4

3 に答える 3

2

おそらく、文字列内の各文字で何かを行う方法を知る必要があるだけでしょうか?

これは、単語を構成する文字列の各文字を調べてから、それらを個別に出力するコードです。は( 、、など)stringと同じインターフェイスを持っていることに気付くでしょう。vectorstr[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(エイリアスのstd::string)リファレンスはおそらく役に立ちます。

于 2013-04-22T23:00:22.957 に答える
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.

}

私はこのコードをテストしませんでした。エラーテストが不足していることは知っていますが、それを行う方法を示しています。

于 2013-04-23T00:56:42.057 に答える
0

ベクトル データ構造を使用して book クラスを保持できます。ベクトル レコード;

于 2013-04-22T23:00:15.900 に答える