0

したがって、2 番目の C++ クラスでは、5 つの構造体とクラスの配列を作成するプログラムを作成する必要があります。struct には、int、5 つの double の配列、および 81 要素の文字配列があります。もちろんユーザーからの情報を取り込む機能もその一つです。その関数は setStructData() と呼ばれます:

    void Prog1Class::setStructData()
{
    for(int i=0; i<5; i++)
    {
        cout<<"input an integer, five doubles, and a character array up to 80 characters."<<endl;
        cin>>StructArray[i].m_iVal;
        for(int j=0; j<5; j++)
        {
            cin>>StructArray[i].m_dArray[j];
        }
        cin.ignore('\n');
        cin>>StructArray[i].m_sLine; 
        cout<<"String entered: "<<StructArray[i].m_sLine<<endl;
    }

} 

次の関数 getStructData() は、構造体の配列の各要素を取得し、配列の 5 つの要素がすべて表示されるまで、その要素を 1 行に、次の行に次の要素を、というようにユーザーに出力します。これは私が持っているものです:

void Prog1Class::getStructData(int index, Prog1Struct *struct_ptr)
{
    struct_ptr=&StructArray[index];
    cout<<struct_ptr->m_iVal<<" ";
    for(int i=0; i<5; i++)
    {
        cout<<struct_ptr->m_dArray[i]<<" "; 
    }
    cout<<struct_ptr->m_sLine<<endl;
}

このプログラムは、キーボード入力 (structarray の各要素を 1 行で入力すること) で入力すると機能しますが、教授から渡されたテキスト ファイル test.txt を使用すると、次のようになります (他の行とは異なる行の文字配列):

10 1.2 2.3 3.4 4.5 5.6 
Test string 1
20 2.3 3.4 4.5 5.6 6.7 
Test string 2
30 3.4 4.5 5.6 6.7 7.8 
Test string 3
40 4.5 5.6 6.7 7.8 8.9 
Test string 4
50 5.6 6.7 7.8 8.9 9.1 
Test string 5

まったく別の行に文字配列があるため、プログラムを台無しにしているテキストファイルです。データを入力している方法だと思いますが、修正方法がわかりません。誰でも私を助けることができますか?I/O リダイレクトを使用して test.txt ファイルを使用してデータを入力すると、最初の行 (文字列なし) が出力され、残りは大量のジャンクになります。助けてください!d

4

1 に答える 1

1

まず、入力が成功したことを常に確認する必要があります。つまり、読んだ後は、ストリームがまだ良好な状態であることを常に確認してください。

if (!(std::cin >> StructArray[i].m_dArray[j])) {
    std::cout << "failed to read double value\n";
}

次に、書式設定された入力を文字配列に使用する場合は、常に最初に幅を設定する必要があります。幅を設定しないと、プログラムに攻撃ベクトルが作成され、ハッキングされる可能性があります (宿題では問題にならないかもしれませんが、専門的なソフトウェアを作成すると、問題になる可能性があります)。

if (!(std::cin >> std::setw(sizeof(StructArray[i].m_sLine)) >> StructArray[i].m_sLine)) {
    std::cout << "failed to read string\n";
}

ただし、フォーマットされた入力は常に最初の空白文字で読み取りを停止することに注意してください。ファイルからの入力には、次の項目が読み取られるためにストリームに残される形式Test stringの文字列が含まれているようです。を使用して、行末まですべての入力を読み取ることができます。ただし、すべてのフォーマットされた入力操作はスペース文字 (数字の後の改行など) を残す傾向があるため、おそらく先頭の空白を読み取る必要があります。たとえば、次のように使用できます。Teststringgetline()

if (!(std::cin >> std::ws).getline(StructArray[i].m_sLine, sizeof(StructArray[i].m_sLine)) {
    ...
}

個人的にはstd::getline(std::cin >> std::ws, str)、2 番目の引数を型として使用することを好みますが、割り当てではクラスstd::stringの使用が許可されていないようです。マニピュレータstd::stringは先頭の空白をすべて読み取ります。 std::ws

于 2013-10-13T20:49:29.297 に答える