2017-07-31 8 views
1

基本的には、ドライバー試験のテストキーを作成してから、試験に合格したかどうかを確認する必要があります。正しい答えは配列に格納され、生徒の答えと完全な名前は、テキストファイルに書き込まれるだけでなく、ユーザー入力から別の配列に格納されます。(C++)配列の内容をファイルに書き込む際に問題が発生しました。

しばらくの間、私はプログラムを実行するまでは正しいと思っていたし、配列の長さに関わらず、その上にアクセントを付けた変なI文字を書き込むことに気づいた。また、配列の正しい答えをファイルに書き込んでいます。これはやりたくありません。

何らかの理由でファイルの最初の文字も切り捨てられています。ファイルに書き込む必要があるのは、(フルネーム、学生の回答(20)、氏名、学生の回答(20)などです。 (例:「John Doe」が「Doe Doe」になる)このエラーの原因は何ですか? cin.ignore()ステートメントがないと、ファイルに必要なフルネームを取得する方法がわかりません。

私は素早くテストするために20の代わりに4つのスペースに変更できるように、配列のサイズを定数として設定しました。

何か助けていただければ幸いです。プログラミングに非常に新しい。これまでのところ、楽しい時があります。

マイコード:

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

void Correct_Answers(const int SIZE, char correctAnswers[]); 
void Submitted_Answers(const int SIZE, char submittedAnswers[]); 
void Get_Name(string &fullName); 



int main() 
{ 
    const int SIZE = 4; 
    char correctAnswers[SIZE]; 
    char submittedAnswers[SIZE]; 
    string fileName; 
    string fullName; 
    char go = 'Y'; 
    ofstream outputObj; 

    Correct_Answers(SIZE, correctAnswers); 

    cout << "\nEnter the file name: "; 
    cin.ignore(); 
    getline(cin, fileName); 
    outputObj.open(fileName); 


    while (go == 'Y' || go == 'y') 
    { 
     Get_Name(fullName); 
     outputObj << fullName << endl; 

     Submitted_Answers(SIZE, submittedAnswers); 
     outputObj << submittedAnswers << endl; 

     cout << "\nTo process another user enter Y. To quit enter N: "; 
     cin >> go; 
    } 


    cout << "\n\n\n"; 
    system("Pause"); 
    return(0); 
} 

void Correct_Answers(const int SIZE, char correctAnswers[]) 
{ 
    int questionCounter = 0; 

    cout << "\nEnter the correct answers for the drivers exam.\n"; 

    for (int x = 0; x < SIZE; x++) 
    { 
     cout << "\tQuestion #" << ++questionCounter << ": "; 
     cin >> correctAnswers[x]; 
     while (correctAnswers[x] != 'A' && correctAnswers[x] != 'a' && correctAnswers[x] != 'B' && correctAnswers[x] != 'b' && correctAnswers[x] != 'C' && correctAnswers[x] != 'c' && correctAnswers[x] != 'D' && correctAnswers[x] != 'd') 
     { 
      cout << "\tInvalid entry. Re-enter answer: "; 
      cin >> correctAnswers[x]; 
     } 
    } 
} 

void Submitted_Answers(const int SIZE, char submittedAnswers[]) 
{ 
    int questionCounter = 0; 

    cout << "\nWelcome to the written portion of the drivers exam!"; 
    cout << "\nDo your best to answer the questions to the best of your knowledge."; 
    cout << "\n15 out of 20 are needed to pass the exam. Best of luck!\n\n"; 

    for (int x = 0; x < SIZE; x++) 
    { 
     cout << "\tQuestion #" << ++questionCounter << ": "; 
     cin >> submittedAnswers[x]; 
     while (submittedAnswers[x] != 'A' && submittedAnswers[x] != 'a' && submittedAnswers[x] != 'B' && submittedAnswers[x] != 'b' && submittedAnswers[x] != 'C' && submittedAnswers[x] != 'c' && submittedAnswers[x] != 'D' && submittedAnswers[x] != 'd') 
     { 
      cout << "\tInvalid. Re-enter answer: "; 
      cin >> submittedAnswers[x]; 
     } 

    } 

} 

void Get_Name(string &fullName) 
{ 
    cout << "\nEnter the users name: "; 
    cin.ignore(); 
    getline(cin, fullName); 
} 
+1

デバッガでコードをステップ実行しようとしましたか? –

+0

私はしていません。私は正直なところ、デバッガの使い方がわからないことを試してみるだろうが、学ぶ方法は一つしかないと思う。ほとんどのものを修正するためにコンパイラエラーメッセージを使用しています。 –

+2

コンパイラエラーは、作成したコードを実行可能ファイルに変換できない場合にのみ発行されます。コンパイルされたすべてのプログラムが正しく動作するわけではありません。デバッガを使用して、デバッガを1行ずつステップ実行し、正しく動作するかどうかを確認します。 –

答えて

0

あなたは、ファイルへの書き込み時に迷惑を取得している理由は、ファイル、ofstreamのオブジェクトに>>演算子を使用する場合、あなたが実際にそれ渡しているということですそれは、行末や空白が見つかるまで文字を読み続けるだけです。例:

int main() 
{ 
    char submittedAnswers[4] = { 'a', 'b', 'c', 'd' }; 
    char * memptr = submittedAnswers; // Points to "abcdÌÌÌ̤ònÉÈø+=" 
    ofstream outputObj ("d:/filetest.txt"); 

    outputObj << submittedAnswers << endl; 
} 

これは、ファイルに迷惑メールを出力する理由です。

あなたが行うので、あなたは「ジョン・ドウ」の最初の文字を失っている理由は次のとおりです。

cin.ignore(); // This discards the first character. 
getline(cin, fullName); 

は、なぜあなたは(cin.ignoreをしますか)?あなたは(cin.ignoreを追加すると思うので)それを動作させるためのラインを読む前に:あなたはcin.ignoreを残せば

cout << "\nEnter the file name: "; 
cin.ignore(); // You've added this because otherwise getline(cin, fileName) 
       // ends up empty 
getline(cin, fileName); 
outputObj.open(fileName); 

はなぜgetlineの())(空の文字列を返すのですか?なぜなら、あなたはそれを呼び出すときにcinバッファに '\ n'改行文字が残っているからです。

あなたはあなたが答え取る:ループで

cin >> correctAnswers[x]; 

を。その行が実行されるたびに、デフォルトで空白と改行がスキップされます。答えを入力するときに何かを入力し、Enterを押します。 Enterキーを押すと、バッファに '\ n'が追加されます。したがってコマンドライン入力はcorrectAnswers []に挿入されますが、最後のcin >>では最後に '\ n'文字で終わるので、getline()を呼び出す前にcin.ignoreを呼び出す必要があります。バッファ内のこの '\ n'文字をスキップします。

関連する問題