C语言里fscanf是如何处理%c与%s的

有字符和字符串相邻时fscanf函数是怎么处理的,
比如从一个文件中读取数据,文件是这样的内容:
1 2014123456 李明 96
a 2014125421 张三 92
...
等多行数据
第1个是1个字符,代表序号,第2个是字符串,学号,第3个是字符串,姓名,第4个是整型,分数
用结构体存放这几个变量

那么下面这段代码就有问题
while(fscanf(fp, "%c%s%[^0-9]%d",&Stu[n].Group, Stu[n].number, Stu[n].name, &Stu[n].Score) != EOF)
n++;

输入的数据会错位

但是改成这样就对了
while(fscanf(fp, "%s%s%[^0-9]%d",&Stu[n].Group, Stu[n].number, Stu[n].name, &Stu[n].Score) != EOF)
n++;

这是为什么?第1个是char Group, 在fscanf里用%c不对,得用%s,是怎么处理的?

再像每行第1个数据是字符串,第2个是字符,则是用的%s %c,这又是为什么?
再比如每行前2个都是字符串,怎么办,3个呢?

帮忙讲解一下fscanf是怎么处理%c和%s的,谢谢

fscanf和scanf一样,只是前者一般从文件中读数据,后者从输入缓冲区读数据。在scanf中,%c只读取一个字符,%s是读取一个字符串——这时会跳过前面的' '、'\t'、'\n'等广义空格直接接收字符,一个接一个地把接收到的字符依次赋给对应的数组元素,当再次遇到' '、'\t'、'\n'等广义空格时认为字符接收完毕,就在刚被赋值的元素后增补一个'\0'以表示本次接收的字符串结束。fscanf的接收过程与此完全一样,只是是从它的第一个文件指针实参指向的文件中读取的;若把fscanf的第一个实参换成stdin(标准输入),它就和scanf一样从键盘读入数据了。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-06-14
请问Stu[n].Group成员是什么类型的?如果是char类型用%c,如果是char *类型,则应该用%s追问

分别是char char char int
即Stu[n].Group成员是char型,但是用%c读取数据就会错位,不知道为什么,它是怎么处理的

追答

应该不会呀,你在格式字符串中加个空格呢?改成这样看看
while(fscanf(fp, "%c %s %[^0-9] %d",&Stu[n].Group, Stu[n].number, Stu[n].name, &Stu[n].Score) != EOF)

追问

好像还是不行,下面这段话是我在网上找的:
%c不会跳空白符(包括空格,换行符,回车符,制表符等等),按顺序读一个字符。
其他的都是自动跳过空白符再读(%d,%e,%g,%f,%s等等所有的),读到下一个空白符为止,读完之后文件指针放到下一个空白符上
不清楚fscanf到底是怎么处理%c和%s的,这两种类型相邻的话读取总是有问题。。。

第2个回答  2014-06-14
while(fscanf(fp, "空格%c%s%[^0-9]%d",&Stu[n].Group, Stu[n].number, Stu[n].name, &Stu[n].Score) != EOF)

吃换行而已追问

真的可以了,请问这是为什么,加空格就数据都对了...

追答

比如说fscanf读完一行(&Stu[n].Score)已经读进去了,这一行还会留一个换行符没有读,所以下一次fscanf会把换行符赋给&Stu[n].Group,后面就会跟着错位,加一个空格表示让fscanf跳过所有空白字符(包括空格TAB回车),所以赋给&Stu[n].Group的就是正确的字符

本回答被提问者采纳
相似回答