0

我已经为此工作了一段时间,但无法修复它。我对 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

对学习什么来修改我的代码的评论将不胜感激。

4

2 回答 2

2

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

于 2013-11-08T22:46:41.567 回答
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(如果有的话;通常除了 d 之外没有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()用于从fileinto读取,string.value直到找到另一个引号。最后一个参数默认为,'\n'但使用 a 读取带引号的字符串'"'是要使用的正确值。终止字符方便地不被存储。
于 2013-11-08T23:03:46.407 回答