c ++将文本文件读入结构数组中不起作用

时间:2013-11-08 22:43:02

标签: c++ arrays

我一直在研究这个问题并且无法修复它。我是C ++的新手。到目前为止,我可以在我的数组中获得10个内容,但输出不清晰,只是一堆数字。我已阅读其他类似代码的帖子但由于某种原因我的工作无效。

输入文本文件是10行假数据,如下所示:

  

56790“喜剧”2012“辛普森一家”18.99 1   56791“恐怖”2003“圆环”11.99 7

我的代码在这里: (我的输出低于我的代码)

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct DVD {
    int barcode;
    string type;
    int releaseDate;
    string name;
    float purchaseprice;
    int rentaltime;
    void printsize();
};

int main () {

ifstream in("textfile.exe");

DVD c[10]; 
int i; 

for (int i=0; i < 10; i++){
in >> c[i].barcode >> c[i].type >> c[i].releaseDate >>
c[i].name >> c[i].purchaseprice >> c[i].rentaltime;
}

for (int i=0;i< 10;i++) {
            cout << c[i].barcode<<" ";
            cout << c[i].type<<" ";
            cout << c[i].releaseDate<<" ";
            cout << c[i].name << " ";
      cout << c[i].purchaseprice << " ";
      cout << c[i].rentaltime << "\n";
        }
return 0;
}

我的输出看起来类似于垃圾,但它有10行像我的数组: -876919876 -2144609536 -2.45e7 2046

对于修改我的代码的研究内容的评论将不胜感激。

2 个答案:

答案 0 :(得分:2)

正如cmbasnett所建议的那样,ifstream in("textfile.exe")读入一个可执行文件。如果您要让程序读入文本文件,则将其更改为ifstream in("textfile.txt")应该有效。

答案 1 :(得分:1)

您始终需要检查输入是否确实正确。由于它在读取10行之前可能会失败,因此您可能还要计算可以成功读取的条目数:

int i(0);
for (; i < 10
       && in >> c[i].barcode >> c[i].type >> c[i].releaseDate
             >> c[i].name >> c[i].purchaseprice >> c[i].rentaltime; ++i) {
    // ???
}

读取第二行的实际问题是引用了字符串,但用于格式化字符串读取的方法并不关心引号。相反,字符串由空格字符终止:字符串的格式化输入将跳过前导空格,然后读取多个字符,直到找到另一个空格。在第二行,它将显示"The然后停止。尝试阅读purchaseprice将失败,因为Ring不是值数值。

要处理该问题,您可能需要将名称quotedstring定义为其输入和输出运算符,例如:

struct quoted_string { std::string value; };

std::istream& operator>> (std::istream& in, quoted_string& string) {
    std::istream::sentry cerberos(in); // skips leading whitespace, etc.
    if (in && in.peek() == '"') {
        std::getline(in.ignore(), string.value, '"');
    }
    else {
        in.setstate(std::ios_base::failbit);
    }
    return in;
}
std::ostream& operator<< (std::ostream& out, quoted_string const& string) {
    return out << '"' << string.value << '"';
}

(请注意,代码不是测试,但我相信它可能会起作用)。

简要说明输入操作符的工作原理:

  1. sentry用于准备输入操作:
    1. 它会刷新tie() d std::ostream(如果有的话;除std::cin外通常没有。)
    2. 它会跳过前导空格(如果有的话)。
    3. 它检查流是否仍未处于故障模式(即,既未设置std::ios_base::failbit也未设置std :: ios_base :: badbit。
  2. 要查看输入是否以引号开头,使用in.peek():此函数返回int,表示操作失败(即,它返回std::char_traits<char>::eof())或下一个流中的字符。代码只是检查它是否返回",因为如果流返回错误或存在任何其他字符,它将失败。
  3. 如果有引号,则使用file.ignore()跳过引号,默认情况下只忽略一个字符(它可以忽略更多字符并指定何时停止的字符)。
  4. 在跳过引号后,std::getline()用于从file读取到string.value,直到找到另一个引号。最后一个参数默认为'\n',但是使用'"'读取引用的字符串是正确的值。方便地,不存储终止字符。