扫描字符导致devC中出现问题

时间:2018-08-30 05:40:15

标签: c string character

所以我的代码执行以下操作:

  1. 请问有什么选择
  2. 如果选项为1:扫描一些数字
  3. 如果选项为2:打印这些数字
  4. 在每个选项之后,询问用户是否要继续选择(是/否)

这是我的主要代码

while(yesnocheck==1)
{
    printf("What's your option?: ");
    scanf("%d",&b);

    switch(b){
        case 1:
            printf("How many numbers?: ");
            scanf(" %d",&n);
            a=(struct sv*)malloc(n*sizeof(struct sv));

            for(int i=0;i<n;i++)
                scanf("%d",&((a+i)->num));
            break;
        case 2:
            for(int i=0;i<n;i++)
                printf("%d\n",(a+i)->num);
            break;
    }
    yesnocheck==yesnochecker();
}

这是yesnochecker函数:

int yesnochecker()
{
    char yesorno;
    printf("Do you want to continue? (Y/N)");

        while(scanf("%s",&yesorno))
    {
        if(yesorno=='Y')
            return 1;
        if(yesorno='N')
            return 0;   
        printf("*Wrong input. Please reenter (Y/N): ");
    }
}

因此在dev C ++上,我的代码无法正确运行。完成选项1后,当我输入“ Y”然后选择选项2时,情况2将显示一些奇怪的数字。但是,它在联机C编译器上运行良好。

然后,当我将yesnochecker()函数中的char yesorno更改为char yesorno[2]并将其视为字符串时,代码确实起作用。

有人可以照亮吗?

1 个答案:

答案 0 :(得分:1)

char cscanf("%s", &c);是个坏主意。 "%s"需要一个缓冲区来存储字符串。适用于char的唯一字符串是一个空字符串(仅由终结符'\0'组成-不太有用)。每个包含1个字符的字符串都需要2 char的存储空间-1个字符,1个终止符('\0')。提供char用于存储是Undefined Behavior

因此,第一个提示是改用正确的格式化程序– "%c"

这会更好,因为它可以删除未定义的行为。但是,它不能解决另一个问题,如以下示例所示:

#include <stdio.h>

int cont()
{
  char c; do {
    printf("Continue (y/n): ");
    scanf("%c", &c);
    printf("Input %c\n", c);
  } while (c != 'y' && c != 'n');
  return c == 'y';
}

int main()
{
  int i = 0;
  do {
    printf("Loop iteration %d.\n", ++i);
  } while (cont());
  /* done */
  return 0;
}

输出:

Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): 
Input '
'
Continue (y/n): n↵
Input 'n'

Live Demo on ideone

是什么?

scanf("%c")从输入中消耗一个字符。另一个字符(为 ENTER 键插入)保留在输入缓冲区中,直到下一次调用任何输入函数为止。

太糟糕了,如果没有 ENTER ,则很难在控制台上确认输入。

一个可能的解决方案是读取字符,直到接收到 ENTER 键(或由于任何原因输入失败)。 (顺便说一句,getc()fgetc()也可以用来读取单个字符。):

#include <stdio.h>

int cont()
{
  int c;
  do {
    int d;
    printf("Continue (y/n): ");
    if ((c = fgetc(stdin)) < 0) {
      fprintf(stderr, "Input failed!\n"); return 0;
    }
    printf("Input '%c'\n", c);
    for (d = c; d != '\n';) {
      if ((d = fgetc(stdin)) < 0) {
        fprintf(stderr, "Input failed!\n"); return 0;
      }
    }
  } while (c != 'y' && c != 'n');
  return c == 'y';
}

int main()
{
  int i = 0;
  do {
    printf("Loop iteration %d.\n", ++i);
  } while (cont());
  /* done */
  return 0;
}

输出:

Loop iteration 1.
Continue (y/n): y↵
Input 'y'
Loop iteration 2.
Continue (y/n): Hello↵
Input 'H'
Continue (y/n): n↵
Input 'n'

Live Demo on ideone

请注意,我将读取字符的类型更改为int。这是因为getc() / fgetc()返回的int可以存储256个可能的char值中的任何一个,以及返回的-1失败的原因。

但是,将int与字符常量(例如'y')进行比较并不是什么问题。在C语言中,字符常量的类型仅为intSO: Type of character constant)。