我一直试图这样做,但有些事情是不行的。我正在尝试建立一个从文本文件中读取学生并创建三个新文件的系统。这三个文件是:正常,失败,新。一切都取决于学生的号码。如果它在开头有'D',那么学生应该找到失败学生的文件。如果号码前面有“我”,学生应该转到名为“新”的文件。如果一开始没有任何内容,学生应该转到“正常”文件。
问题是,如果用户手动将学生数据插入文件,一切正常。但是我有一个函数可以读取学生的数据并将其插入主文件中。如果数字前面没有任何内容,当我尝试从文件中读取所有学生时,一切正常。但如果有一个字母,则数据不会写入正确的(任何)文件中。
以下是示例:让我们有一个包含数据的就绪文件:
989123 John Brown //Should go to the "Normal" file
I112233 Steve Round //Should go to the "New" file
D101010 Wayne Bruce //Should go to the "Failed" file
如果我尝试读取数据并将其插入正确的文件,一切正常。 但是,假设用户已从应用程序菜单中选择“添加学生”选项。并且用户插入新记录。例如:
D818181 Some Guy //Should go to the "Failed" file
但它没有去那里。我不知道是什么原因。如果用户输入的学生编号没有任何字母,则一切正常,但如果有字母则不会显示在文件中。我希望你明白了。这是代码。我们将不胜感激。
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct Student
{
int number;
string name;
string secondName;
};
Student Failed[50], New[50], Normal[50];
int o = -1;
int v = -1;
int n = -1;
int MakeInt(string number, bool ignoreFirst)
{
int num;
if(ignoreFirst)
{
number[0] = '0';
num = atoi(number.c_str());
}
else
{
num = atoi(number.c_str());
}
return num;
}
void zapis_student(string number, string name, string secondName)
{
if(number[0] == 'D')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name= name;
temp.secondName = secondName;
o++;
Failed[o] = temp;
}
else if(number[0] == 'I')
{
int num = MakeInt(number, true);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
v++;
New[v] = temp;
}
else
{
int num = MakeInt(number, false);
Student temp;
temp.number = num;
temp.name = name;
temp.secondName = secondName;
n++;
Normal[n] = temp;
}
}
void ReadFile()
{
ifstream fp("studenti.txt", ios::in);
if(fp.fail())
{
cout<<"Error!"<<endl;
}
while(fp.good())
{
string number, name, secondName;
fp >> number >> name >> secondName;
zapis_student(number, name, secondName);
}
fp.close();
}
void sortir(Student a[], int br)
{
for(int i = 0; i < br; i++)
{
for(int j = 0; j < br-1; j++)
{
if(a[j].number>a[j+1].number)
{
Student buf = a[j];
a[j] = a[j+1];
a[j+1] = buf;
}
}
}
}
void MakeFile(Student a[], int br, char ime_fail[])
{
ofstream fp(ime_fail);
for(int i = 0; i < br; i++)
{
fp << a[i].number << " " << a[i].name << " " << a[i].secondName << endl;
}
fp.close();
}
void AddStudent()
{
fstream fp("studenti.txt", ios::app);
string number, firstName, secondName;
cin >> number >> firstName >> secondName;
fp << number << " " << firstName << " " << secondName << endl;
fp.close();
}
void SortStudents()
{
sortir(Failed, o);
sortir(New, v);
sortir(Normal, n);
}
int main ()
{ int ans;
do
{ cout<<"******************************Menu***********************************"<<endl;
cout<<"* *"<<endl;
cout<<"* 1. Add student. *"<<endl;
cout<<"* 2. Read file. *"<<endl;
cout<<"* 3. Sort students. *"<<endl;
cout<<"* 4. Make Normal file. *"<<endl;
cout<<"* 5. Make Failed file. *"<<endl;
cout<<"* 6. Make New file. *"<<endl;
cout<<"* 7. Exit! *"<<endl;
cout<<"* *"<<endl;
cout<<"*********************************************************************"<<endl;
cout<<endl<<"Choice: "<<endl;
do
{cin>>ans;} while((ans<1)||(ans>7));
switch(ans)
{ case 1:AddStudent();break;
case 2:ReadFile();break;
case 3:SortStudents();break;
case 4:MakeFile(Normal, n, "Normal.txt");cout<<"Suzdaden e fail NovaGrupa.txt!\n";break;
case 5:MakeFile(Failed, o, "Failed.txt");cout<<"Suzdaden e fail Izklucheni.txt!\n";break;
case 6:MakeFile(New, v, "New.txt");cout<<"Suzdaden e fail Vlizashti.txt!\n";break;
case 7:exit(1);
}
}
while(ans!=7);
}
答案 0 :(得分:4)
每种类型只有一名学生;因为你从-1开始,你用0完成读数,这是第一个元素的正确索引,但错误的元素数量!要解决这个问题,我建议你从0开始,使用索引然后递增。 E.g。
int o = 0;
...
Failed[o] = temp;
o++;
(交换了行),以便o
保留到目前为止你读过的那种学生的数量。
注意:你还需要正确处理文件的结尾并处理atoi
无法转换为整数的情况:无论如何都要尝试(和你一样)没有办法注意到它),并且“正常”计数可以是一个单位更大(在修复之后;在修复之前,它是正确的计数!)
atoi
(您应该包含cstdlib
,但不要使用)... 不要忽略编译器警告 MakeFile
的最后一个论点应为const char *