C++从文件中读取
C++ Reading from a file
我一整天都在尝试这样做,但有些地方不太好。我正在尝试创建一个系统,从文本文件中读取学生并创建三个新文件。这三个文件分别是:正常、失败和新建。一切都取决于学生的号码。如果它的开头有"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的名称不正确
相关文章:
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 读取文件的最后一行并输入到链接列表时出错
- 为什么在读取文件大小时文件IO速度会发生变化
- 读取文件时运行时的未知行为
- 如何逐行读取文件,每行中的内容都用空格分隔并将其写入新文件中
- 读取文件中所有可能的十六进制 16 字节序列并打印每个序列
- C++ 读取文件读取文件不正确
- 读取文件并将其存储在unordered_map中时出现问题
- 读取文件时无法使用 OpenMP 获得加速
- 使用istringstearm和get行缓慢读取文件
- 如何继续读取不同功能中的文件,而不是从头开始再次读取文件?
- 读取文件时引发异常
- 从标准输入读取文件后读取用户输入
- 在读取文件后重置句柄
- 如何在C++编译时读取文件?
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 读取文件在第二次调用时返回INVALID_HANDLE
- 通过指针读取文件
- 逐行读取文件,并将数据插入变量和数组中