0

あるファイルを読み取り、別のファイルに書き込み、画面に出力するプログラムを作成しました。つまり、読み取り、書き込み、印刷の3つのことを実行することになっています。

プログラムは、「Chap_11_employee_data.txt」という名前のファイル内のレコード数もカウントすることになっています。ただし、以下を表示しているだけです。

**Total Records 0** 
    The End

ファイルに書き込むと、-858993460などの奇妙な数字も表示されます。私はほとんどすべてを試したので、ここでアカウントを登録することになりました。私のコードは、私が読み込もうとしているファイルと書き込もうとしているファイルとともに、以下にリストされています。

お時間をいただき、誠にありがとうございます。

コード:

#include <iostream>
#include <fstream>  
#include <iomanip>  
using std::cin;
using std::cout;
using std::endl;
using std::setw;
using std::ios;

using std::ifstream;
using std::ofstream;

const int EMPLOYEES = 20; 
const int MAX = 21;  

int ReadData( ifstream &inFile, ofstream &outFile, char name[][MAX], int age[] );
void WriteOutputFile( ofstream &outFile, char name[ ][MAX], int age[ ], int counter );
void PrintTotalsAndSummary( ofstream &out, int totalRecords );

int main()
{   
    char name[EMPLOYEES][MAX]; 
    int age[EMPLOYEES];
    int record_counter(0);

    ifstream inFile;    

    ofstream outFile( "Chap_11_Report.txt" );  

    inFile.open( "Chap_11_employee_data.txt" );  

    if ( inFile.is_open() )   
    {   
        record_counter = ReadData( inFile, outFile, name, age );
        inFile.close();

        if( outFile.is_open() )
        {   
            WriteOutputFile( outFile, name, age, record_counter );
            PrintTotalsAndSummary( outFile, record_counter );
            outFile.close();            
        }   
        else
        {   
            cout << "Trouble Opening File";  
            cout << "\n\n\t\t ** About to EXIT NOW! ** ";
        }   
    }   
    else
    {   
        cout << "Trouble Opening File";
        cout << "\n\n\t\t ** About to EXIT NOW! ** ";
    }   
    return 0;
}
int ReadData( ifstream & inFile, ofstream & outFile, char name[][MAX], int age[] )
{   
    int counter = 0;
    inFile >> name[counter] >> age[counter]; // Priming Read

    while ( !inFile.eof() )
    {
        cout << setiosflags( ios::left ) << setw( 25 )
            <<  name[counter] << resetiosflags( ios::left )
            << setw( 4 ) << age [counter] << endl;
        counter++;
        inFile >> name[counter] >> age[counter];
    }

    return counter;
}


void WriteOutputFile( ofstream &outFile, char name[][MAX], int age[], int counter)
{
    outFile << "   Here is the Output File" << endl;
    for ( int r = 0; r <= counter; r++ )
    {
        outFile << setiosflags( ios::left ) << setw( 25 )
            << name[r] << setw( 4 )
            << resetiosflags( ios::left ) << age[r]
            << endl;
    }
}

void PrintTotalsAndSummary( ofstream &outFile, int totalRecords )
{
    // To screen
    cout  << "\n\n\t** Total Records: " << totalRecords << " **\n"
        << "\t\t The End \n";

    // To file
    outFile << "\n\n\t** Total Records: " << totalRecords << " **\n"
        << "\t\t The End \n";
}

私が読んでいるファイル(Chap_11_employee_data.txt):

"Alexis","Blough",1-1921,"CEO"
"Bill","Pay",1-7711,"Accounting"
"Willy","Makit",4-1595,"Sales"
"Marie","Murray",1-4986,"MIS"
"Cal","Caldwellowinski",5-0911,"MIS"
"Jamie","Johanasola",5-9999,"Marketing"

私が書き込んでいるファイル(Chap_11_Report.txt):

Here is the Output File
                     -858993460


    ** Total Records: 0 **
         The End 
4

2 に答える 2

2

これがあなたの入力ステートメントです...

inFile >> name[counter] >> age[counter]; 

そして、出力ファイル形式はこれです...

"Alexis","Blough",1-1921,"CEO"
"Bill","Pay",1-7711,"Accounting"

入力ステートメントは、スペースまたは終了文字に遭遇するまで名前を読み取ります。したがって、最初のケースでは、単語間にスペースがないため、行全体が読み取られます。次に、int である age を入力します。最初から文字でいっぱいの 2 行目から年齢の入力を開始します。整数ストリーム内の文字は未定義の動作です。それが間違った結果を得ている理由です。

問題は、ファイル形式と入力形式の不一致です。それらを同期してみてください。

空白も読み取るには、inFile.get()またはを使用しますinFile.getline()

于 2012-11-25T07:01:27.330 に答える
1

あなたの読書には1つの問題があります:

while ( !inFile.eof() )

問題は、ストリームが eof() ではない方法で悪化する可能性があることです。これが発生すると、無限ループに陥ります。したがって、実際には bad() を確認する必要があります。

while ( !inFile.bad() ) // check for eof and other error cases.

通常、このテストは完全に間違っています。しかし、次のことを行うことで、これを回避することができました。

<Get Input>

while ( !inFile.bad() )
{
    < DO WORK>
    <Get Input>
}

以下を使用して、(より慣用的な方法で) 同じ効果を実現できます。

while ( <Get Input> )
{
    < DO WORK>
}

読み取り (>> または std::getline() を使用) は、ストリームへの参照を返します。これがブール コンテキスト (while ループ テストなど) で使用される場合、bad を使用して取得されるストリームの状態を表す bool (実際には言語弁護士の場合と同様の bool) に変換されます。したがって、読み取りが実際に機能した場合にのみ、ループ本体に入ります。

入力ストリーム オペレータは非常に単純化されており、入力に失敗すると、ストリーム内に内部エラー ビットが設定され、エラー ビットがリセットされるまでそれ以上の入力が提供されなくなります。

あなたが提供した入力を考えると、これは失敗します:

inFile >> name[counter] >> age[counter];

変数name[counter]は C 文字列を表し、入力演算子 >> が C 文字列に適用されると、最初の空白文字 (この場合は改行) まで読み取られます。したがって、ここでは次のように割り当てます。

"Alexis","Blough",1-1921,"CEO"

この値に。

age[counter]次に、整数値を使用して読み取りを続行します。これは以下から整数を読み込もうとします:

"Bill","Pay",1-7711,"Accounting"

'"'文字が数字ではないため、これは失敗します。

あなたがすべきことは次のとおりです。

std::string  name;
std::getline(inFile, name, ','); // Read upto the ',' character (and discard it)
// You may want to remove the quotes here.

int age = 0;
// Age is not defined in the input so set it manually.

std::string  line;
std::getline(inFile, line);      // Read and ignore the rest of the line.
于 2012-11-25T07:44:20.353 に答える