使用与fgets和sscanf意外repitition [英] Unexpected repitition using fgets and sscanf

查看:158
本文介绍了使用与fgets和sscanf意外repitition的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的code的一部分。 的目的,可获得的sscanf 是扫描正好一个空格分隔的三个变量。如果获得通过,然后输出指令一次。否则,输出错误和退出程序。

Here is a part of my code. The aim of gets and sscanf is to scan three variables separated by exactly one space. If passed, then output the instruction again. Otherwise, output error and exit program.

我想用7长度的字符数组以限制行数,越来越格式只喜欢G 3 3。但似乎有些不对劲,我code。

I want to use 7 length char array to limit the number in the line, getting format like 'g 3 3' only. But it seems something wrong in my code.

#include <stdio.h> 

int main (void) {
    char line[7];
    char command;
    int x, y;

    while(1){
        /* problem: g  4 4 or g 4  4 can also pass */
        fgets(line, 7, stdin);
        nargs = sscanf(line, "\n%c %d %d", &command, &x, &y);

        if(nargs != 3){
          printf("error\n");
          return 0;
        }

        printf("%c %d %d\n", command, x, y);
    }
}

意外:

g  4 4
g 4 4
error

预期:

g 4 4
g 4 4
// I can continue type

谁能告诉我,为什么它仍然会重复指令?

Can anyone tell me why it will still repeat the instruction?

推荐答案

据该的 C11标准,7.21.6.2p5

的空白字符(多个)构成的指令通过读输入到第一非空白字符(这仍然是未读),或直到没有更多的字符可读取执行。

A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read.

这说明 \\ n 指令和两个空格字符作为是在功能相同的:他们会匹配尽可能多的连续的空格(空格,制表符,换行符,等),因为它们可以从输入

This describes the \n directive and the two space characters as being identical in functionality: They'll match as much consecutive white-space (spaces, tabs, newlines, etc) as they can from the input.

如果你想匹配一个空格(只有一个空格),我建议使用%* 1 [] 而不是空白指令。你可以使用%* 1 [\\ N] 来同样丢弃换行符。例如,由于出现换行符的在一行的末尾的:

If you want to match a single space (and only a single space), I suggest using %*1[ ] instead of the white-space directives. You could use %*1[\n] to similarly discard a newline. For example, since the newline character appears at the end of a line:

nargs = sscanf(line, "%c%*1[ ]%d%*1[ ]%d%*1[\n]", &command, &x, &y);

这并不能彻底解决你的问题,不幸的是,%d个格式说明也被定义为丢弃的空白字符的:

This won't completely solve your problem, unfortunately, as the %d format specifier is also defined to discard white-space characters:

输入空白字符(由 isspace为函数指定)被跳过,除非该规范包括 [ C N 说明

Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier

一些聪明的黑客,你也许可以继续使用的sscanf (或更好,但 scanf函数无中间缓冲),但在成本方面可维护性比较后的选择,我们可能也只是使用的getchar ,所以如果你正在寻找一个解决问题的方法是反对回答您提出的问题,我建议你 gsamaras答案

With some clever hacks, you might be able to continue using sscanf (or better yet, scanf without the intermediate buffer), but after comparing the alternatives in terms of cost on maintainability, we might as well just use getchar, so if you're looking for a solution to your problem as opposed to an answer to the question you posed, I'd recommend gsamaras answer.

这篇关于使用与fgets和sscanf意外repitition的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆