-2

テキスト ファイルを読み込んで、その内容を構造体のベクトルにインポートしようとしています。

ここに私の定義があります

typedef struct
{
    string pcName, pcUsername, pcPassword, pcMessage, pcAdvertisement; //I know that
                  //this is incorrect convention. It was originally a char*
}
ENTRY;

vector<ENTRY> entries;
fstream data;

ここに私の表示データ関数があります

void DisplayData()
{
    std::cout << (int)(entries.size() / 5) <<" entries" << endl; 
    for(int i = 1; i <=(int)entries.size()/5; i++)
    {
        cout << endl << "Entry " << i << ":" << endl
             << "Name: " << entries[i].pcName << endl
             << "Username: " << entries[i].pcUsername << endl
             << "Password: " << entries[i].pcPassword << endl
             << "Message: " << entries[i].pcMessage << endl
             << "Advertisement: " << entries[i].pcAdvertisement << endl;
    }
}

ここに私の Load Data 関数があります

bool LoadData(const char* filepath)
{
    std::string lineData ;
    int linenumber = 1 ;
    data.open(filepath, ios::in);
    ENTRY entry_temp;

    if(!data.is_open())
    {
        cerr << "Error loading file" << endl;
        return false;
    }

    while(getline(data, lineData))
    {
             if(linenumber==1) {entry_temp.pcName            = lineData;}
        else if(linenumber==2) {entry_temp.pcUsername        = lineData;}
        else if(linenumber==3) {entry_temp.pcPassword        = lineData;}
        else if(linenumber==4) {entry_temp.pcMessage         = lineData;}
        else if(linenumber==5) {entry_temp.pcAdvertisement   = lineData;}

        entries.push_back(entry_temp);

        if(linenumber == 5)
        {
            linenumber = 0; 
        }

        linenumber++;

    }
    data.close();

    puts("Database Loaded");
    return true;
}

読み込んでいるテキストファイルは次のとおりです。

Name1
Username1
Password1
Message1
Ad1

load data を呼び出した後の表示データ関数の結果は次のとおりです。

1 entries
Entry 1:
Name: Name1
Username Username1
Password:
Message:
Advertisement:

ご覧のとおり、最初の 2 つはロードされますが、最後の 3 つはロードされません。ベクトルの代わりに配列を使用してこれを行ったとき、うまく機能したので、何が間違っているのかわかりません。ありがとう。

4

3 に答える 3

3

あなたのDisplayData関数は少し奇妙で、あなたのLoadData.

すべての行で現在のエントリの新しいコピーをプッシュLoadDataバックします。ENTRIES1 から開始し (これはベクトルまたは配列の先頭ではありませDisplayDataん)、ベクトル全体の 1/5 エントリまでしか反復しません。

これには大幅な手直しが必要です。

まず、size()標準コンテナーのメンバーは、含まれている要素の数を返し、含まれている構造体のフィールドの数を考慮しません。

今後の参考のために、すぐにコンパイルできる完全なスタンドアロンの例で質問を投稿してください。( http://sscce.org/を参照)

正しく実行されるこの変更されたデータを試して、何が異なっているかがわかるかどうかを確認してください。

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

typedef struct
{
        string pcName, pcUsername, pcPassword, pcMessage, pcAdvertisement;
}
ENTRY;

vector<ENTRY> entries;
fstream data;

bool LoadData(const char* filepath)
{
    std::string lineData ;
    int linenumber = 1 ;
    data.open(filepath, ios::in);
    ENTRY entry_temp;

    if(!data.is_open())
    {
        cerr << "Error loading file" << endl;
        return false;
    }

    while(getline(data, lineData))
    {
             if(linenumber==1) {entry_temp.pcName            = lineData;}
        else if(linenumber==2) {entry_temp.pcUsername        = lineData;}
        else if(linenumber==3) {entry_temp.pcPassword        = lineData;}
        else if(linenumber==4) {entry_temp.pcMessage         = lineData;}
        else if(linenumber==5) {entry_temp.pcAdvertisement   = lineData;}


        if(linenumber == 5)
        {
            entries.push_back(entry_temp);
            linenumber = 0; 
        }

        linenumber++;

    }

    data.close();

    puts("Database Loaded");
    return true;
}

void DisplayData()
{
    std::cout << entries.size() <<" entries" << endl; 
    for(int i = 0; i < entries.size(); i++)
    {
        cout << endl << "Entry " << i << ":" << endl
             << "Name: " << entries[i].pcName << endl
             << "Username: " << entries[i].pcUsername << endl
             << "Password: " << entries[i].pcPassword << endl
             << "Message: " << entries[i].pcMessage << endl
             << "Advertisement: " << entries[i].pcAdvertisement << endl;
    }
}

int main()
{
    LoadData("/tmp/testdata");
    DisplayData();
    return (0);
}
于 2013-06-11T00:27:21.543 に答える
3

各行をデータ フィールドに直接読み込むことをお勧めします。

getline(data, entry_temp.pcName);
getline(data, entry_temp.pcUsername);
getline(data, entry_temp.pcPassword);
getline(data, entry_temp.pcMessage);
getline(data, entry_temp.pcAdvertisement);
entries.push_back(entry_temp);

これにより、現在の while ループよりも意図がはるかに明確になります。また、入力行ごとに 1 つのエントリを作成するのではなく、4 つの入力行すべてに対して 1 つのエントリを作成します (残りの 3 つを空白にします) これで、ファイルの最後に到達したかどうかを確認する while ループを使用して、いくつかの「エントリ」を読み取ることができます。

これを行うと、ベクターのエントリ数が予想の 5 倍ではなく正確になるため、データの出力がはるかに簡単になります (必要以上に多くのメモリを消費します)。

于 2013-06-11T00:31:30.890 に答える