我对C中的文件处理非常陌生,我想问几个问题!
特别是,我不确定fscanf()和fgets()是否会逐行自动递增文件指针。根据我对测试和文档的理解,fscanf()一次只能将文件指针移动1个字符/类型;但fgets()似乎逐行读取文件(因为它遇到换行符时终止)。从文档中,fscanf()将忽略任何空格字符。那么这是否意味着即使我有逐行输入文件,fscanf将无法逐行读取它?即使我指定了确切的格式,换行符也不会被保留?
特别是,如果一行包含10个非空白部分(单词,整数,双精度等),但我只指定其中3个被读入变量(使用%*或者根本不放任何东西) ),这些读取函数会做什么?
例如,我的输入文件如下所示:
9 opls_182 9 DNP CT 9 0.140 12.0110
10 opls_182 10 DNP CT 10 0.140 12.0110
11 opls_145 11 DNP CA 11 -0.115 12.0110
12 opls_145 12 DNP CA 12 -0.115 12.0110
我只想阅读opls_182和CT和9部分(第2,第5和第6列)。 使用fgets()和sscanf(),我会这样写:
fgets(fp,500,buffer);
sscanf(buffer, "%*s %s %*d %*s %s %d %*f %*f", variables);
or this:
sscanf(buffer, "%*s %s %*d %*s %s %d %*s", variables);
or this:
sscanf(buffer, "%*s %s %*d %*s %s %d", variables);
这三个功能是否会以相同的方式工作?那么在第二个版本中,最后一个%* s会解析整个最后两列,还是只解析最后一列? (%s似乎从非白色空格字符开始到非白色空格字符)。
如果我有比每行中的部分更多的说明符怎么办?是否会出现错误或额外变量只保持0 /空?
如果我使用fscanf(),只有第一个版本能正常工作,而第二个和第三个版本会弄乱读数,因为fscanf()不会自动跳转,对吗?
scanf函数中的所有格式说明符都将忽略空格字符。但是,如果我想跳过第一部分([bonds])并读取最后一个整数,有没有办法做一些像%* some_format%d(忽略直到找到整数)? %[^ format]会工作吗?我尝试了%[^%d]或%[^ d],要么只停留在角色" d"并给予" [bon"。我知道您可以使用%[^]指定要排除的字符数,但是,如果该数字在整个文件中发生变化,则无法使用此方法。
我发现C中的读/写功能非常强大,但要做到这一点也很棘手。非常感谢你们!
答案 0 :(得分:0)
规则非常简单:fgets()
读取整行,除非行的长度超过提供的缓冲区,在这种情况下,它会尽可能多地读取。另一方面,fscanf()
读取你告诉它的内容,跳过前面的空格。例如,给定一行"1 2 3"
(不带引号),fgets()
将读取整行,而fscanf(fp, "%d %d", &i1, &i2)
将读取两个整数并将它们存储到提供的地址,并留下{{1 (注意包括空格)未读。
在第二次" 3"
调用中,最后一个sscanf()
仅解析第二列到最后一列。如果你想跳过所有内容直到行尾,请使用%*s
之类的内容。你是正确的,如果你使用%*[^\n]
,只有第一个版本可以做你想要的,因为fscanf
将换行视为另一个空格。您仍然可以使用fscanf()
格式说明符修复fscanf()
版本。
%*[^\n]
无法“搜索”输入,它必须始终根据指定的格式进行解析。没有相当于scanf
正则表达式的格式。
您的.*
调用将无法执行您想要的操作,因为scanf
的第一个实例会占用剩余的字符串,因此只会处理两个格式字符。但是,如果您将%s
替换为%s
,它将完全符合您的要求(对于此输入)。