2017-07-31 158 views
1

学校任务。必须基本上为驾驶员考试创建一个测试钥匙,然后验证学生是否通过了考试。正确的答案将被存储在一个数组中,学生的答案和全名将被存储在用户输入的另一个数组中,并写入一个文本文件。(C++)将数组内容写入文件时出现问题

有一段时间我以为我在做什么是正确的,直到我去运行该程序,并注意到无论数组长度多长时间,它都会写出一个奇怪的I字符,并且上面有一个口音。它还将数组的正确答案写入我不想做的文件中。所有我需要写入的文件是:(全名,学生答案(20),全名,学生答案(20)等)。

该文件的第一个字母也由于某种原因被切断。 (例如“John Doe”变成“ohn Doe”)这个错误的原因是什么?没有cin.ignore()语句我不知道如何获得我需要的全名到文件中。

我已经将数组大小设置为常数,允许我将其更改为4个空格而不是20个,以便进行快速测试。

任何帮助表示赞赏。编程极其新颖。有时享受它有时很难。

我的代码:

#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

仅当您编写的代码无法转换为可执行文件时才会发出编译器错误。并非所有编译的程序都能正常工作,甚至可以定义的方式工作。您可以使用调试器逐行检查它是否正常工作。 –

回答

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()读取线为它工作之前:

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.ignore()?因为在调用cin缓冲区时,仍然存在'\ n'换行符。

当你把你的答案:

cin >> correctAnswers[x]; 

在一个循环。每当该行执行时,默认跳过空格和新行。当你输入一个答案时,你输入一些内容然后按回车。当你按回车键时,它会向缓冲区添加一个'\ n'。所以命令行输入被插入到correctAnswers []中,但是在最后一个cin >>中,最后以'\ n'结尾,这就是为什么在调用getline()之前必须调用cin.ignore的原因。 ,在缓冲区中跳过这个'\ n'字符。