我知道%d格式说明符,当在fscanf()中使用时,会读取一个整数并忽略其前面的空白,包括换行符(我已对其进行了验证)。但是在下面的程序中,我使用fscanf()来从多行(每个行包含3个整数)的文件读取时,格式字符串"%d%d%d%*c"与"%d%d%d"一样好。

为什么会这样呢?由于fscanf()与%d一起用作格式说明符字符串中的第一个格式说明符,所以忽略了整数前的任何空格,为什么用作最后一个说明符的额外%*c不会引起任何错误或侧面错误-如果%d说明符在一行中每组3个数字之后都没有忽略换行符,那么%*c就很有意义了,因为它会吃掉换行符。但是为什么即使没有错误或副作用,它也能正常工作如果fscanf()默认情况下忽略%d的空白?当%* c找不到要吃的字符并且说明符和输入之间不匹配时,fscanf()不应该停止扫描吗?不匹配时fscanf()是否应该停止,就像scanf()一样吗?

编辑:即使我使用"%*c%d%d%d",它也能正常工作!一旦格式说明符和开头的输入之间不匹配,是否应该停止后续字符的扫描和处理?

#include

#include

int main ()

{

int n1,n2,n3;

FILE *fp;

fp=fopen("D:\\\\data.txt","r");

if(fp==NULL)

{

printf("Error");

exit(-1);

}

while(fscanf(fp,"%d%d%d%*c",&n1,&n2,&n3)!=EOF) //Works as good as line below

//while(fscanf(fp,"%d%d%d",&n1,&n2,&n3)!=EOF)

printf("%d,%d,%d\",n1,n2,n3);

fclose(fp);

}

这是我的文件data.txt中数据的格式:

243 343 434

393 322 439

984 143 943

438 243 938

输出:

243 343 434

393 322 439

984 143 943

438 243 938

请参阅与使用fscanf()关联的注释以从给定行读取。 它恰好涵盖了这种情况。

@JonathanLeffler是的,这就是我想问的。您说%d skips white space to the first digit。它证明了我最初在问题中说的话。%d应该注意空格,包括换行符,所以为什么%*c不使用 格式说明符字符串的任何地方(甚至开头)都会导致问题?

考虑问题中程序的这种变化:

#include

#include

int main(int argc, char **argv)

{

char *file ="D:\\\\data.txt";

FILE *fp;

char *formats[] =

{

"%d%d%d%*c",

"%d%d%d",

"%*c%d%d%d",

};

if (argc > 1)

file = argv[1];

for (int i = 0; i < 3; i++)

{

if ((fp = fopen(file,"r")) == 0)

{

fprintf(stderr,"Failed to open file %s\", file);

break;

}

printf("Format: %s\", formats[i]);

int n1,n2,n3;

while (fscanf(fp, formats[i], &n1, &n2, &n3) == 3)

printf("%d, %d, %d\", n1, n2, n3);

fclose(fp);

}

return 0;

}

重复打开效率不高,但是这里不必担心。明确和显示行为更为重要。

它被编写为(a)使用在命令行上指定的文件名,因此我不必使用D:\\data.txt之类的名称,它们在Unix系统上创建非常不便,并且(b)显示了三种格式使用。

给定问题的数据文件:

243 343 434

393 322 439

984 143 943

438 243 938

该程序的输出为:

Format: %d%d%d%*c

243, 343, 434

393, 322, 439

984, 143, 943

438, 243, 938

Format: %d%d%d

243, 343, 434

393, 322, 439

984, 143, 943

438, 243, 938

Format: %*c%d%d%d

43, 343, 434

393, 322, 439

984, 143, 943

438, 243, 938

请注意,当%*c是格式的第一部分时,第一个数字的第一位将被使用。读取前三个数字后,%*c读取行中第三个数字之后的换行符,然后%d跳过其他空格(除非没有空格)并读取该数字。

否则,该行为将在下面的评论中进行阐述,很大程度上是从另一个相关问题中提出的。

相关问题使用fscanf()从给定行读取的一些正在讨论的代码是:

fscanf(f,"%*d %*d %*d%*c");

fscanf(f,"%d%d%d", &num1, &num2, &num3);

我注意到代码应该测试fscanf()的返回值。但是,对于三个%*d转换规范,如果在到达指定行之前遇到了EOF,则可能会得到EOF的返回值。不幸的是,直到执行第二个fscanf(),您才知道第一行包含字母而不是数字。您也应该测试第二个fscanf()。您可能会得到EOF,或者0或1或2(所有这些都表示问题),或者您可能会得到3表示成功3次转换。请注意,在格式中添加\意味着将跳过空白行,但是无论如何都会发生这种情况; %d将空格跳到第一位。

Is there any other way we can read but ignore entire lines like I clumsily did with fscanf(f,"%*d%*d%*d")?Is using %*[^\

] the nearest thing one can do for this?

跳过整行的最好方法是使用fgets(),如我答案中代码的最新版本所示。显然,如果这些行中的任何一个超过4095字节,它就有可能误计数行。太太,那是不可能的。

I have a confusion now and I don't want to put it in a question. So can you tell me this—fscanf() ignores whitespace automatically, so after the first line, when three integers are read and ignored according to my %*d%*d%*d specifier, I expect fscanf() to ignore the newline too when it starts reading in the next run of the loop. But why doesn't my additional %*c or \ cause problems and the program runs fine when I use %*d%*d%*d%*c or %*d%*d%*d\ in my code?

您无法确定这些格式在哪里出了问题;您可以检测到EOF,否则,fscanf()将返回0。但是,由于%*d会跳过前导空格-包括换行符-您是否会在使用%*c的第三个数字之后读取换行符并不重要是否存在,并且当您有\时,这是一个空格,因此读取将跳过换行符和任何尾随或前导空格,并在到达非空格字符时停止。当然,您也可以在三个数字中间添加换行符,或者一行中可以包含三个以上的数字。

请注意,当用户在终端上键入时,格式尾随\尤其奇怪。用户按下回车键,并继续按下回车键,但是该程序直到用户键入非空白字符后才继续。这就是为什么fscanf()在数据不可靠时很难使用的原因。只要可靠,就很容易,但是如果出现任何问题,诊断和恢复将很痛苦。这就是为什么最好使用fgets()和sscanf()的原因;您可以控制要解析的内容,可以根据需要使用其他格式重试,并且可以报告整行,而不仅仅是fscanf()无法解释的内容。

请注意,%c(和%*c)不会跳过空白。因此,格式末尾的%*c会读取(并丢弃)读取的数字后的字符。如果这是换行符,则表示已读取并忽略了该字符。扫描集%[...]是另一个转换规范,不会跳过空格。所有其他标准转换规范都跳过前导空白。

很高兴您加入了答案!!

让我们在这里省略%*d部分,这与我们在使用%d%d%d无关,而%*c在这里是真正的问题……就像它的存在不影响代码的原因一样。

是什么让他放松了自己的答案?其中的讨论有很多东西要存档。

他获得了两次否决票(我都没有),我还不清楚原因,但我可以同情删除两个否决票的答案。请注意,这个问题以及数十个相关问题明确说明了为什么处理scanf()和亲属的所有详细信息如此困难。它们确实是向初学者教授的棘手功能!

@RppellsVulture我放弃了。 :)似乎我很想念这一点,就像乔纳森(Jonathan)所说的那样,我真的不在乎留下不赞成投票的答案,但不确定该如何解决。

@JonathanLeffler需要100k +声誉的人投票否决另外100k +声誉的人,所以既然这是关于我不属于或不太可能属于的俱乐部的全部,我应该停止考虑。

@RppellsVulture嗯?我认为没有这样的限制,我认为(希望!)如果他们不同意我的回答,任何人都可以投票否决我。至少我不了解任何此类限制。

@unwind我的意思是,我在SO期间甚至还没有投票赞成10k +的人,所以忘了100k +的人的答案。尽管我已经看到50k +的人在指出时删除了他们的错误或答案,但是同样,它花费了50k +家伙首先发现他们的错误。

fscanf()成功时,该函数返回已成功填充的参数列表的项目数。 由于匹配失败,读取错误或文件结尾的范围,此计数可以与预期的项目数匹配或更少(甚至为零)。

上面的段从不谈论停止不匹配的情况,它也会尝试使用额外的说明符,因为没有输入,所以它只会返回成功扫描的数字。如果格式说明的参数过多,则多余的参数将被忽略。 如果没有足够的参数用于格式说明,则结果不

每三个数换行 用C语言表示,关于换行符:使用fscanf()读取每行3个数字的文件,为什么“%d%d%d%* c”和“%d%d%d”一样好?...相关推荐

  1. 7-105 sdut-C语言实验——三个数排序7-106 sdut-C语言实验——模拟计算器7-107 sdut-C语言实验——找中间数

    目录 7-105 sdut-C语言实验--三个数排序 7-106 sdut-C语言实验--模拟计算器 7-107 sdut-C语言实验--找中间数 7-105 sdut-C语言实验--三个数排序 分数 ...

  2. C语言中三个数排列大小,C语言三个数排列大小的实现方法

    这个题简单,也有很多的方法,在这里我想用数学的方法解决排序问题.ps:本人是个学渣,程序写的不好,欢迎各位大神指点帮助. 梳理思路: 以1 2 3为例 先考虑我们所有的可能输入类型(这里不一一列举): ...

  3. c语言中如何排出三个数的大小,C语言比较三个数大小

    C语言比较三个数大小 首先比较第一个数和第二个数的大小,如果第一个数大于第二个数,则将第一个数和第二个数互换,不大于则不作处理:然后将第二个数和第三个数比较,同样,若大于则将它们互换:最后比较完以后, ...

  4. 输入三个整数x,y,z,请把这三个数由小到大输出(C语言函数)

    程序分析:我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换, 然后再用x与z进行比较,如果x>z则将x与z的值进行交换,这样能使x最小. #include ...

  5. c语言fscanf读入字符串,fscanf读取多行 怎么用fscanf读入文件下一行

    python+django MTV框架 和php MVC框架的不同之处后来当朋友再问起小编你还那么喜欢他吗,小编终于可以低头微笑摇着头说不了.您教导小编们不要说废话,可在小编眼里您说的全是废话! py ...

  6. 三个数比较大小-C语言

    三个整数比较大小--C语言 [C语言] 代码如下: //初学小白一枚,如有不足之处,还望各位大佬多多指教 #include<stdio.h> //标准输入输出头文件 int main() ...

  7. c#三个数从小到大排序_C语言实现三个数从小到大排序/输出

    任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序. 实现过程: (1)定义数据类型,本实例中 a.b.c.t 均为基本整型. (2) 使用输入函数获得任意 3 个值赋给 a.b.c. ( ...

  8. c语言怎么写入换行字符,C语言中的换行符是什么:要么 ?

    C中的换行符是什么? 我知道不同的操作系统具有不同的行尾字符,但是它们被转换为C换行符. 那是什么角色? .在读取或写入文本模式文件或stdin / stdout等时,必须使用,C会为您处理翻译.当您 ...

  9. shell编程100例之输入三个数并进行升序排序

    shell编程100例之输入三个数并进行升序排序 #!/bin/bash# 依次提示用户输入 3 个整数,脚本根据数字大小依次排序输出 3 个数字 read -p "请输入一个整数:&quo ...

最新文章

  1. 三级网络技术_计算机三级网络技术(1):网络系统结构与设计的基本原则
  2. Ubuntu xrdp 遠端桌面連線
  3. 23种设计模式的索引
  4. 4.1.6 OS之文件的基本操作原理(创建、删除、打开、关闭、读-写)
  5. docker 查看日志_8个优秀Docker容器监控工具,收藏了
  6. [转载] 1022 D进制的A+B (20分)【java题解】【80ms】
  7. 蔚来ET5将于2022年9月开启交付 补贴前售价32.8万元起
  8. 《REINFORCEMENT LEARNING (DQN) TUTORIAL》的学习笔记
  9. 链接mysql_JavaScript学习笔记(二十四)-- MYSQL基础操作
  10. 小程序 | 云数据库模糊查询
  11. lj245a引脚功能图_74HC245引脚图应用电路与中文资料
  12. CGGame资源(转)
  13. 一键实现视频二维码分享功能,So easy!
  14. 投资组合管理-风险分散与马科维茨均值方差模型
  15. JAVA无法读取jvm.cfg_“could not open `C:\Program Files\Java\jre7\lib\amd64\jvm.cfg”问题解决办法...
  16. Nacos 极简入门
  17. 钢铁侠马斯克的野望:实现载人航天,开源特斯拉自动驾驶!
  18. (仿)火车头采集器 源码开源
  19. 数据挖掘:数据清洗——数据噪声处理
  20. 5W1H分析法(登陆)

热门文章

  1. 立体神经网络模拟连续不完备系统
  2. js三进制计算机,js 笔记 - 二进制位运算符
  3. 【控制】《多智能体系统一致性协同演化控制理论与技术》纪良浩老师-第9章-二阶连续时间时延多智能体系统加权一致性
  4. 玩转Mixly – 3、Arduino AVR编程 之 控制
  5. TCL with SNPS llengthlappendget_cellsget_ports
  6. FPGA篇(九)关于ASCII码
  7. Ember 3.9 发布,3.8 升级为 LTS
  8. 写在方法中的路由跳转
  9. html固定table表头的实现思路
  10. Error处理:/bin/bash^M: 坏的解释器: 没有该文件或目录(bad interpreter: No such file or directory)...