前言
又是一年的实验周,我们两个星期就只做一个ACM题,所以就早早做完了,然后认识的一个王大美女她的实验周代码出了点问题,让我帮着看一看。题目要求也不难,就是从文本逐行读取数据,但是我看了几十分钟也没找到解决的方法(/(ㄒoㄒ)/~~),然后在今天早上才找到解决的方法,在这里特别说明一下。
实现
我就偷一下王大美女的数据,希望她看不到。。
序号 学号 姓名 班级 平时成绩 期中成绩 期末成绩
01 B13040301 王红 B130403 40 86 90
02 B13040302 李阳 B130404 30 85 0
03 B13040303 张明 B130402 60 80 87
04 B13040304 张杨 B130403 66 78 78
05 B13040305 冯先 B130406 77 90 76
06 B13040306 于浩华 B130404 81 67 56
07 B13040307 张明宇 B130402 50 87 57
08 B13040308 红叶枫 B130401 56 89 84
09 B13040309 甘先锋 B130403 68 76 94
10 B13040310 蔡凤辉 B130403 45 67 98
这就是保存在文本文件中的数据,然后定义了一个Student的结构体,通过读取文本文件中的数据,给Student数组进行赋值。看起来应该很简单,但是偏偏就出了问题,主要是不知道该怎么进行换行,就是把文件指针移动到下一行的开头。所以我就采用了另外的一种方法,间接的去移动文件的指针,然后就可以实现文件的逐行读取了。
这里我需要的说明的就是ifstream的getline函数,这个函数有很多种参数,这个倒是无所谓,它的主要功能是读取文本数据一行的内容,如下面的参数情况getline(char* s,int length) 这个就是读取一行length个字节的内容赋值到s中,当然如果遇到换行符就提前结束了,这也是为什么能读取一行的原因。当读取完一行之后,就把文件指针移动到下一行的开头,然后再调用的时候就从下一行开头开始读取了。
利用这样的特性,我们可以先读取第一行的内容使用ifstream的操作符“>>”这个操作符可以给变量赋值,从文件指针指向的地方开始读取数据赋值,然后调用getline函数读取了第二行的内容但是不使用读取的数据,因为使用了getline函数,所以文件指针就移动到第三行,然后再使用操作符“>>”进行赋值,以此循环。等读取完奇数行的数据之后,我们再从偶数行开始读取,跳过奇数行,这样就可以读取完全部的数据了。
这样的方法是有要求的,要求你的文本文件的数据必须按照一定的形式进行输入,而且中间不允许出现空行,否则就会出现错误。
之所以进行这样处理的原因是“>>”操作符再读取到一行结束的时候不能把文件指针移到下一行开头,所以只能借助getline函数来间接实现,但是因为getline函数,我们就只能隔一行读一行了。当然肯定会有移动文件指针的方法,我找了一点资料但是没有找到,所以暂时就这么来吧,如果有更好的方法,希望大家不吝赐教。
源码
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
struct Student
{
string serialNumber;
string studentNumber;
string name;
string classNumber;
int usualGrade;
int midGrade;
int finalGrade;
double sumGrade;
};
void readData(ifstream &file,Student& stu)
{
file >> stu.serialNumber >>stu.studentNumber>>stu.name>> stu.classNumber >> stu.usualGrade >> stu.midGrade >> stu.finalGrade >> stu.sumGrade;
}
int readStuInfo(Student stu[])
{
ifstream fileB("B.txt"),fileA("B.txt");
if (!fileB)
{
cout << "没有找到需要读取的B.txt,请将文件放到指定位置再次运行本程序。" << endl << " 按任意键以退出";
return -1;
}
char dustBin[200];
int i,j;
for (i = 0; !fileA.eof(); i+=2)
{
fileA.getline(dustBin, 80);
readData(fileA,stu[i]);
}
fileA.close();
fileB.getline(dustBin, 80);
for(j=1;!fileB.eof();j+=2)
{
fileB.getline(dustBin, 80);
readData(fileB,stu[j]);
}
fileA.close();
int count = i>j?i-2:j-2;
return count;
}
typedef struct Student Student;
int main()
{
Student stu[100];
int count = readStuInfo(stu);
for(int i=0;i<count;i++)
{
cout<<stu[i].serialNumber<<" "<<stu[i].studentNumber<<" "<<stu[i].classNumber<<endl;
}
}