【问题标题】:How to skip stuff in a file using fscanf?如何使用 fscanf 跳过文件中的内容?
【发布时间】:2015-10-20 02:56:55
【问题描述】:

我正在学习 C 文件操作,并且遇到一个特定问题,我需要将字母(A-Z、a-z)存储为从文件中读取的字符串。所以,如果我有abcd&*dvcd,那么abcd 是一个字符串,dvcd 是一个字符串。

基本上我有两个问题:

  1. 我事先不知道要存储的字符串的大小。
  2. 我需要跳过非字母字符

我想我会通过使用 fscanf 格式字符串来解决这两个问题。这是我的想法。我需要以某种方式跳过使用fscanf 格式字符串来查找我在文件中的位置。然后,我可以从保存的起始位置中减去我需要的字符串 malloc。然后,我 malloc 指定长度的字符串,然后,我可以回到保存的位置并实际读取它。

但是,我不知道如何告诉fscanf 不存储扫描的字符串?

或者是否有其他方法可以跳过非字母字符?

【问题讨论】:

  • 您应该仔细查看fscanf() 上的 POSIX 文档,看看您是否可以使用这些文档——诸如 m 修饰符之类的功能可以在 %ms 中使用。您应该查看“扫描集”(%[…])和* 来禁止分配。更重要的是,您应该查看标准 C fgets() 或 POSIX getline()sscanf() 的结合使用。这通常更容易。
  • @JonathanLeffler 哦。您的意思是将文件中的字符串存储在内存中?我不认为这是可行的,因为我将使用非常大的文本文件的程序......
  • 您还打算将它存储在哪里?它不需要使用比您计划做的更多的内存——如果您不走运,每个字符串可能多 32 个字节。您可以在读取和处理每一行后删除字符串 - 否则会泄漏内存。
  • 使用 fgets,我怎么知道字符串长度是多少?它可能是一个跨越多行的字符串
  • 根据问题陈述,字符串不能跨越多行,因为换行符不在集合 a...z 或 A...Z 中

标签: c string scanf


【解决方案1】:

您可以在 fscanf 的格式说明符中使用格式说明符,例如“%[a-zA-Z]”。 就像下面的例子,

#include<stdio.h>
int main()
{
        char a[10];
        fscanf(stdin, "%[a-zA-Z]", a);
        printf("%s\n",a);
}

在此示例中,它仅读取标准输入中的字母。它会跳过非字母字符。

【讨论】:

    【解决方案2】:

    由于@suresh 的答案是not working for me(输出应该是asd gddf 而不是asd asd),我已经写了另一个版本,它不是那么短但对我来说很好:

    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    int main(void) {
        char ch;
        while(scanf("%1c", &ch) == 1) { //while we have characters to read
            if(isalpha(ch)) { // if the next one is alphanumeric
                ungetc(ch, stdin); // we put it back
                char str[101];
                scanf("%100[a-zA-Z]", str); // to read the whole string (including that char)
                printf("found string %s\n", str);
            }
        }
        return 0;
    }
    

    Here 是一个可行的 ideone 示例。我为此使用标准输入,但您可以轻松地调整它以使用您打开的另一个文件。我用于scanf (%100[a-zA-Z]]) 的格式说明符意味着它最多只能读取100 个字符(str 的大小),只包含小写或大写字母。 %1c 表示单个字符,unget 将字符放回缓冲区以避免如果它不是符号则跳过它。

    编辑:正如@m-m 指出的那样,在方括号内使用- 不是标准的,在某些实现中可能不可用。如果您无法使用,您可以随时使用%100[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]

    【讨论】:

    • %[ 中使用- 是实现定义的;一些标准库可能不支持您所依赖的行为
    猜你喜欢
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 2016-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多