0

我有一个文本文件,其中列出了对象类的某些属性,例如 DVD 标题(字符串)类别(字符串)价格(int)运行时(int)发布年份(int)

该文件被列为

Movie1
Action    
10.45
123
2008

Movie2
Sc-fi
12.89
99
2008

我有一个功能,您可以输入文件名,它应该将不同的属性读入一个对象

DVD* file(DVD arr[], string fileName, int s, int& e)
{
ifstream file(fileName);

DVD j;
string v;
string w;
double x;
int y;
int z;


while(!file.eof())
{
    file >> v;
    j.setTitle(v);

    file >> w;
    j.setCategory(w);

    file >> x;
    j.setPrice(x);

    file >> y;
    j.setRuntime(y);

    file >> z;
    j.setYear(z);

    arr=add(arr, j, s, e); //this is just a function that adds the object to an arry
}


file.close();

return arr;
}

但它不能正常工作,我希望它将每一行读入变量,然后如果有空格跳过它,但如果不是文件末尾,请继续读取,直到它碰到一个字符串。有什么建议么?

4

1 回答 1

1

两件事情。

首先:

while(!file.eof())直到尝试读取后才返回eof()true

第二件事是,如果您想逐行阅读,最好使用以下内容:

void read_file(std::vector<DVD> & arr, string fileName) {
    ifstream file(fileName.c_str());

    DVD j;
    std::string line;
    enum State {
        TITLE, CATEGORY, PRICE, RUNTIME, YEAR
    } state = TITLE;

    while(std::getline(file, line)) {

        // if we encounter an empty line, reset the state    
        if(line.empty()) {
            state = TITLE;
        } else {

            // process the line, and set the attribute, for example
            switch(state) {
            case TITLE:
                j.setTitle(line);
                state = CATEGORY;
                break;
            case CATEGORY:
                j.setCategory(line);
                state = PRICE;
                break;
            case PRICE:
                j.setPrice(boost::lexical_cast<double>(line));
                state = RUNTIME;
                break;
            case RUNTIME:
                j.setRuntime(boost::lexical_cast<int>(line));
                state = YEAR;
                break;
            case YEAR:
                j.setYear(boost::lexical_cast<int>(line));
                arr.push_back(j);
                state = TITLE;
                break;
            default:
                // just in case
                state = TITLE;
                break;
            }
        }
    }
}

这是有效的,因为std::getline返回一个引用,当在布尔上下文中使用时,true如果最后一个操作使流处于“良好”状态,则该引用将是。

在此示例中,我根据boost::lexical_cast<>需要将字符串转换为数字类型,但您可以std::stringstream手动执行此操作,或者您认为最适合您的任何其他方法。例如,atoi()strtolstrtod等。

旁注:std::vector<DVD>使用而不是原生数组要好得多。它会同样快,但会为您正确处理调整大小和清理。您将不再需要您的add功能,因为您将能够:arr.push_back(j);

于 2013-10-20T19:06:36.190 回答