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

这是我的加载数据功能

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

这是调用加载数据后显示数据函数的结果:

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

如您所见,前两个加载但后三个不加载。当我使用数组而不是向量执行此操作时,它工作得很好,所以我不知道我做错了什么。谢谢。

4

3 回答 3

3

你的DisplayData功能有点奇怪,你的LoadData.

您每行都LoadData推回当前条目的新副本。ENTRIESDisplayData从 1 开始(这不是任何向量或数组的开头),并且仅迭代到整个向量的 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 循环更清晰。它还为所有 4 个输入行创建一个条目,而不是为每个输入行创建一个条目(其他三个为空白)。现在,您可以使用 while 循环来读取多个“条目”,该循环检查您是否已到达文件末尾。

这样做也将使打印数据变得更加容易,因为向量的条目数将与您预期的一样多,而不是您预期的五倍(这也消耗了比您需要的更多的内存)。

于 2013-06-11T00:31:30.890 回答
2

虽然我认为@code-guru 的想法是正确的,但我会将同样的想法更进一步,让您的代码与标准库更紧密地协同工作。我会通过使用流提取器读取数据项并使用流插入器显示它来做到这一点。所以,提取器看起来像这样:

std::istream &operator>>(std::istream &is, ENTRY &e) { 
    getline(is, e.pcName);
    getline(is, e.pcUsername);
    getline(is, e.pcPassword);
    getline(is, e.pcMessage);
    getline(is, e.pcAdvertisement);
    return is;
}

..插入器看起来像这样:

std::ostream &operator<<(std::ostream &os, ENTRY const &e) {
    os << e.pcName << "\n";
    os << e.pcUsername << "\n";
    os << e.pcPassword << "\n";
    os << e.pcMessage << "\n";
    os << e.pcAdvertisement << "\n";
    return os;
}

有了这些,加载和显示数据变得相当简单。

加载数据:

std::ifstream in("yourfile.txt");

std::vector<ENTRY> data((std::istream_iterator<ENTRY>(in)),
                         std::istream_iterator<ENTRY>());

显示数据:

for (auto const & e: data)
    std::cout << e << "\n";

目前,我还没有尝试复制您用来显示数据的格式——大概对此的修改应该是相当明显的。

于 2013-06-11T00:53:10.190 回答