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

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) {
    // ???
}

2行目を読む際の実際の問題は、文字列が引用符で囲まれていることですが、文字列のフォーマットされた読み取りに使用されるアプローチは引用符を気にしません。代わりに、文字列は空白文字で終了します。文字列の書式設定された入力は、先頭の空白をスキップし、別の空白が見つかるまで多くの文字を読み取ります。2行目で、読み取り"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::failbitstd::ios_base::badbit も設定されていないか) をチェックします。
  2. 入力が引用符で始まるかどうかを確認するには、in.peek()を使用します。この関数はint、操作が失敗したことを示す を返します (つまり、 を返しますstd::char_traits<char>::eof())、またはストリーム内の次の文字を返します。"コードは、ストリームがエラーを返すか、他の文字が存在する場合に失敗するかどうかをチェックするだけです。
  3. 引用符がある場合、引用符はスキップfile.ignore()され、デフォルトでは 1 文字だけが無視されます (さらに多くの文字を無視して、停止する文字を指定することができます)。
  4. 先頭の引用符をスキップした後、別の引用符が見つかるまでstd::getline()読み取るために使用されますfilestring.value最後のパラメーターはデフォルトで に設定されていますが'\n'、a を使用して引用符で囲まれた文字列を読み取る'"'場合は、正しい値を使用してください。終了文字は、便宜上、保存されません。
于 2013-11-08T23:03:46.407 に答える