gpt4 book ai didi

c++ - 读取文件: How file pointer is moved using fscanf and how scanf/fscanf work with missing %type

转载 作者:行者123 更新时间:2023-11-30 17:31:37 27 4
gpt4 key购买 nike

我对 C 语言的文件处理非常陌生,我想问几个问题!

  1. 我经常使用 fscanf/fget 将文件转换为不同的格式。不过我不太清楚 fscanf 和 fgets 之间的区别。

特别是,我不确定 fscanf() 和 fgets() 是否会自动逐行递增文件指针。根据我对测试和文档的了解,fscanf() 一次仅将文件指针移动 1 个字符/类型;但 fgets() 似乎是逐行读取文件(因为它在遇到换行符时终止)。从文档来看,fscanf() 将忽略任何空白字符。那么这是否意味着即使我有一个逐行输入文件,fscanf 将无法逐行读取它?即使我指定了确切的格式,换行符也不会被保留?

  1. 对于所有 fscanf/scanf()/sscanf(),我不确定如何解析字符串。

特别是,如果一行包含 10 个非空白部分(单词、整数、 double 等),但我只指定其中 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() 不会自动跳线,对吧?

  1. 此问题与模式线有关:[ bond ] 387

scanf 函数中的所有格式说明符都将忽略空白字符。但是,如果我想跳过第一部分([ bond ])并读取最后一个整数,有什么方法可以执行类似 %*some_format %d 的操作(忽略直到找到整数)? %[^format] 有效吗?我尝试了 %[^%d] 或 %[^d],两者都只会停在字符“d”处并给出“[ bon”。我知道您可以使用 %[^] 指定要排除的字符数,但是,如果该数字在整个文件中发生变化,则无法使用此方法。

  1. 如果所有部分都没有空格地连接在一起,scanf 是否能够区分不同的格式。例如:9opls_182DNPCT91.40STUI8。模式 %d%s%d%s%f%s%d 可以读出:9、opls_、182、DNPCT、91.40、STUI、8?

我发现C语言的读/写功能非常强大,但要正确使用也很困难。非常感谢你们!

最佳答案

  1. 规则非常简单:fgets() 读取整行,除非该行的长度超过提供的缓冲区,在这种情况下它会读取尽可能多的内容。另一方面,fscanf() 会读取您告诉它的内容,并跳过前面的空格。例如,给定一行 "1 2 3" (不带引号),fgets() 将读取整行,而 fscanf(fp, "%d %d", &i1, &i2) 将读取两个整数并将它们存储到提供的地址,并保留 "3" (注意包括空格)不读取。

  2. 在第二次 sscanf() 调用中,最后一个 %*s 仅解析倒数第二列。如果您想跳过所有内容直到行尾,请使用类似 %*[^\n] 的内容。您是正确的,如果您使用 fscanf,只有第一个版本可以执行您想要的操作,因为 fscanf() 将换行符视为另一个空格。不过,您可以使用 %*[^\n] 格式说明符修复 fscanf() 版本。

  3. scanf 无法“搜索”输入,它必须始终根据指定的格式对其进行解析。没有与 .* 正则表达式等效的格式。

  4. 您的 scanf 调用不会执行您想要的操作,因为 %s 的第一个实例将吃掉剩余的字符串,因此只会处理两个格式字符。但是,如果您将 %s 替换为 %[^0-9],它将完全按照您的要求执行(对于此输入)。

关于c++ - 读取文件: How file pointer is moved using fscanf and how scanf/fscanf work with missing %type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24523431/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com