【问题标题】:Can I set non-alphabetic characters as a delimeter in c when using fscanf?使用 fscanf 时,我可以在 c 中将非字母字符设置为分隔符吗?
【发布时间】:2018-03-05 19:07:51
【问题描述】:

我正在尝试使用

从文件中读取字符串
while(fscanf(fd, "%s ", word) != EOF) {}

fd 是文件,word 是我存储字符串的位置。 但是,这有效地使用了空白作为分隔符。目前,如果我有一个读取“this% is, the4 str%ng”的文件,它将导致字符串“this%”、“is”、“the4”和“str%ng”。我需要它是“this”“is”“the”“str”“ng”。是否可以使用 fscanf 执行此操作,或者我需要使用其他东西吗?

我看到了一些答案 herehere 但他们似乎没有帮助我。

【问题讨论】:

  • fscanf() 返回扫描的项目数。那怎么可能是EOF?
  • 来自手册页“如果在任何转换之前发生输入失败,则返回值EOF”。但将返回值与预期转化次数进行比较更好

标签: c string scanf delimiter


【解决方案1】:

这些答案显示了"%[] 格式说明符的使用。举个例子,假设你有这个从控制台获取两个字符串:

#include <stdio.h>

int main(void){
    char s1[100] = "", s2[100] = "";
    int res;

    res = scanf("%99[^%]%%%99[^%]%%", s1, s2);
    printf("%d %s %s\n", res, s1, s2);
}

第一个 % 启动每个格式规范,^% 告诉 scanf 停止在 %,下一个“转义”双 % 告诉 scanf 读取停止扫描。然后它对第二个字符串重复,所以一个字符串的格式规范是 %99[^%]%%

为了让格式看起来更简单,假设分隔符不是%而是#,那么代码就是:

#include <stdio.h>

int main(void){
    char s1[100] = "", s2[100] = "";
    int res;

    res = scanf("%99[^#]#%99[^#]#", s1, s2);
    printf("%d %s %s\n", res, s1, s2);
}

fscanf 的功能类似。


编辑

此答案不处理“未知”分隔符,因此我修改了代码。

#include <stdio.h>

int main(void){
    char s1[100] = "";
    while(scanf("%99[^!£$%&*()_-+={};:'@#~,.<>/?0123456789]", s1) == 1) {
        getchar();                      // remove the delimiter
        printf("%s\n", s1);
    }
}

请注意,我没有包含字符 ^"[] 作为分隔符。

【讨论】:

  • 这是一个很好的例子,但我想知道为什么我从未见过[ 格式规范。检查并注意到这似乎是 POSIX 指定的分隔符。所以它可能在 Windows 中不起作用(我在 MSDN 中没有看到它)。 msdn.microsoft.com/en-us/library/hf4y5e3w.aspx
  • @Afshin 我改进了答案,这确实适用于 MSVC。
  • @Afshin "%[scan_set]" 在标准 C 库中定义良好。如果在 windows 中使用的编译器是兼容的,它也可以在那里工作。这不是操作系统问题,而是编译器/库问题。
【解决方案2】:

如果您没有特定的分隔符(似乎是您的情况),则需要手动解析每个文件行。您可以使用fgets() 读取每一行,然后手动解析(例如忽略每个非字母字符)。

问候

【讨论】:

  • 很遗憾,已经失去了编写字符处理代码的技巧。字符数组只能通过将库调用串在一起来处理:)
猜你喜欢
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多