如何在scanf()中使用不同的数据类型?

如何在scanf()中使用不同的数据类型?,c,scanf,C,Scanf,我正在用C语言开发一个国际象棋游戏,只是为了练习。在游戏开始时,用户可以键入4项内容: 行列(即22) “h”表示需要帮助 “q”退出 如何使用scanf期望2个整数或1个字符?最好完全避免使用scanf。它通常会造成比它解决的问题更多的麻烦 一种可能的解决方案是使用fgets获取整行,然后使用strcmp查看用户是否键入“h”或“q”。如果没有,请使用sscanf获取行和列。似乎最明智的做法是阅读整行,然后确定其中包含的内容。这不包括使用scanf,因为它会消耗stdin流中的内容 试着这

我正在用C语言开发一个国际象棋游戏,只是为了练习。在游戏开始时,用户可以键入4项内容:

  • 列(即
    22
  • “h”表示需要帮助
  • “q”退出

如何使用
scanf
期望2个整数或1个字符?

最好完全避免使用
scanf
。它通常会造成比它解决的问题更多的麻烦


一种可能的解决方案是使用
fgets
获取整行,然后使用
strcmp
查看用户是否键入“h”或“q”。如果没有,请使用
sscanf
获取行和列。

似乎最明智的做法是阅读整行,然后确定其中包含的内容。这不包括使用
scanf
,因为它会消耗
stdin
流中的内容

试着这样做:

char input[128] = {0};
unsigned int row, col;
if(fgets(input, sizeof(input), stdin))
{
    if(input[0] == 'h' && input[1] == '\n' && input[2] == '\0')
    {
        // help
    }
    else if(input[0] == 'q' && input[1] == '\n' && input[2] == '\0')
    {
        // quit
    }
    else if((sscanf(input, "%u %u\n", &row, &col) == 2))
    {
        // row and column
    }
    else
    {
        // error
    }
}

这个只是使用scanf

#include <stdio.h>
int main()
{
        char c;
        int row, col;
        scanf("%c", &c);
        if (c == 'h')
                return 0;
        if (c == 'q')
                return 0;
        if (isdigit(c)) {
                row = c - '0';
                scanf("%d", &col);
                printf("row %d col %d", row, col);
        }
        return 0;
}
#包括
int main()
{
字符c;
int row,col;
scanf(“%c”、&c);
如果(c='h')
返回0;
如果(c=='q')
返回0;
if(isdigit(c)){
行=c-‘0’;
scanf(“%d”列和列);
printf(“行%d列%d”,行,列);
}
返回0;
}

p.S.:那些没有仔细阅读和理解我的答案的人,请尊重自己,不要随意投反对票

除了“获取整行,然后使用sscanf”之外,逐字读取直到输入“\n”也是一种更好的方法。如果程序遇到“h”或“q”,它可以立即执行相关操作,同时还可以为输入流提供实时分析

例如:

#define ROW_IDX 0
#define COL_IDX 1
    int c;
    int buffer[2] = {0,0};
    int buff_pos;
    while( (c = getchar())) {
        if (c == '\n') {
            //a line was finished
            /* 
            row = buffer[ROW_IDX];
            col = buffer[COL_IDX];
            */
            buff_pos = 0;
            memset(buffer , 0 , sizeof(buffer));//clear the buffer after do sth...
        } else if (c == 'h') {
            //help
        } else if (c == 'q') {
            //quit
        } else {
            //assume the input is valid number, u'd better verify whether input is between '0' and '9'
            if (c == ' ') {
                //meet whitespace, switch the buffer from 'row' to 'col'
                ++buff_pos;
            } else {
                buffer[buff_pos%2] *= 10;
                buffer[buff_pos%2] += c - '0';
            }
        }
    }

我建议你先读这行,然后试着在上面使用两种不同的
sscanf
s。到目前为止你都试过什么?这有助于向我们展示您拥有的功能,因此我们可以在此基础上继续发展。这个答案:我认为对您很有帮助。@Rodrigalves去搜索如何使用函数
fgets
sscanf
,等等。制作一些使用它们的玩具程序。我相信你不需要花太多的精力就能掌握它们。
fgets
无法在一次呼叫中可靠地获得整个线路。当然,在这种情况下这不是一个问题,因为我们不需要超过3个字符,但在不同的情况下,这可能是一个问题。@Joker\u vD:是什么阻止你调用
fgets
并扩展缓冲区直到你到达新行?@Joker\u vD如果你是说
fgets
可能只得到部分行,因为必须指定要读取的最大字符数,这实际上是一件好事,与
get
相比,
fgets
不会导致缓冲区溢出。但你要小心这个事实是对的。@YuHao祝贺你的10公里:)你是一个快速得分手!嗯,真的。事实证明,我工作的所有C项目都包含一个旧的实用程序文件,它提供了
getline()
。意识到
stdio
不能一行一行地读出来然后返回,这让我非常不安。+1我将
IFs
sscanf
解决方案与@Daniel's一起使用answer@DanielKamilKozar这段代码看起来应该可以工作。它应该接受由空格分隔的两个数字。请记住,scanf按format语句读取,它不一定要读取完整的行+1.@SakthiKumar:正常的,是的。电脑游戏中的一个可以大得多。:)如果只从stdin读取1个字节,则访问未初始化的变量,并且处于UB中。快速解决方法就是初始化输入数组
#define ROW_IDX 0
#define COL_IDX 1
    int c;
    int buffer[2] = {0,0};
    int buff_pos;
    while( (c = getchar())) {
        if (c == '\n') {
            //a line was finished
            /* 
            row = buffer[ROW_IDX];
            col = buffer[COL_IDX];
            */
            buff_pos = 0;
            memset(buffer , 0 , sizeof(buffer));//clear the buffer after do sth...
        } else if (c == 'h') {
            //help
        } else if (c == 'q') {
            //quit
        } else {
            //assume the input is valid number, u'd better verify whether input is between '0' and '9'
            if (c == ' ') {
                //meet whitespace, switch the buffer from 'row' to 'col'
                ++buff_pos;
            } else {
                buffer[buff_pos%2] *= 10;
                buffer[buff_pos%2] += c - '0';
            }
        }
    }