c语言字符串堆栈,c - 如何使用fscanf()格式字符串 - 堆栈内存溢出

fscanf(input_fp, "%30[^ ,\n\t]%30[^ ,\n\t]%30[^ ,\n\t]", ...

不会在文本文件中使用','或'\\ n'。 随后的fscanf()尝试也会失败,并返回值0(不是EOF)会导致无限循环。

对于fgets()/sscanf() fscanf()解决方案可以更好地处理潜在的IO和解析错误:

main()

{

FILE *input_fp;

FILE *output_fp;

char buf[100];

while (fgets(buf, sizeof buf, input_fp) != NULL)

{

char name[30]; // Insure this size is 1 more than the width in scanf format.

char age_array[30];

char occupation[30];

#define VFMT " %29[^ ,\n\t]"

int n; // Use to check for trailing junk

if (3 == sscanf(buf, VFMT "," VFMT "," VFMT " %n",

name, age_array, occupation, &n) && buf[n] == '\0')

{

// Suspect OP really wants this width to be 1 more

if (fprintf(output_fp, "%-30s%-30s%-30s\n", name, age_array, occupation) < 0)

break;

} else

break; // format error

}

fclose(input_fp);

fclose(output_fp);

}

而不是调用ferror(),而是检查fgets(),fprintf()的返回值。

可疑OP的未声明字段缓冲区为[30],并相应地调整了scanf()。

有关if (3 == sscanf(buf, VFMT "," ...

if (3 == sscanf(...) && buf[n] == '\\0') {在以下情况下为真:

1)精确地使用3个"%29[^ ,\\n\\t]"格式说明符,每个scanf至少使用1个字符。

2)buf [n]是字符串的结尾。 n通过“%n”说明符设置。 “%n”中的前一个''导致最后一个"%29[^ ,\\n\\t]"之后的任何后续空格被消耗。 scanf()看到“%n”,它指示它设置从扫描开始的当前偏移量,以将其分配给&n所指向的int。

编译器将"VFMT "," VFMT "," VFMT " %n"连接到

" %29[^ ,\n\t], %29[^ ,\n\t], %29[^ ,\n\t] %n".

我发现前者比后者更易于维护。

" %29[^ ,\\n\\t]"的第一个空格指示sscanf()扫描(消耗并不保存)0个或多个空格('','\\ t','\\ n'等)。 其余的命令sscanf()消耗并保存除“,”,“ \\ n”,“ \\ t”之外的任何1到29个字符,然后附加一个“ \\ 0”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值