C++从文件中读取

C++ Reading from a file

本文关键字:读取 文件 C++      更新时间:2023-10-16

我一整天都在尝试这样做,但有些地方不太好。我正在尝试创建一个系统,从文本文件中读取学生并创建三个新文件。这三个文件分别是:正常、失败和新建。一切都取决于学生的号码。如果它的开头有"D",学生应该转到失败学生的档案中。如果数字前面有"I",学生应该转到名为"New"的文件。如果一开始什么都没有,学生应该转到"正常"文件。

问题是,如果用户手动将学生数据插入到文件中,一切都可以。但我有一个功能可以读取学生的数据并将其插入到主文件中。如果数字前面什么都没有,当我试图从文件中读取所有学生时,一切都可以。但是,如果有一封信,数据就不会写入正确的(任何)文件中。

下面是一个例子:让我们有一个包含数据的现成文件:

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);
}

每个类型只有一个学生;因为您从-1开始,所以您以0结束读取,这是第一个元素的正确索引,但元素计数错误!要解决此问题,我只建议您从0开始,使用索引,然后递增。例如

int o = 0;

Failed[o] = temp;
o++;

(换了几行),这样o就可以记录到目前为止你读过多少这类学生。

注意:您还需要正确处理文件结尾,并处理atoi无法将任何内容转换为整数的情况:您无论如何都要尝试(但您没有办法注意到),并且"正常"计数可以大一个单位(在修复之后;在修复之前,这是正确的计数!)

其他建议

  • 不要使用atoi(应该包括cstdlib,但没有)…不要忽略编译器警告
  • MakeFile的最后一个参数应为const char *
  • 为变量使用更好的名称:o、v、n的名称不正确