【问题标题】:How to read a single character with getchar in C?如何在 C 中使用 getchar 读取单个字符?
【发布时间】:2016-11-24 08:11:40
【问题描述】:

我正在用 C 语言创建一个菜单驱动程序,我必须要求用户输入,然后在我的程序中只使用输入的第一个字符。除了下面的代码之外,我还尝试了#define MAX_CHAR 1 并在while 循环中使用它而不是EOF 等等。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void print_menu();
void uppercase(char *string); 

int main()
{
    char i = 0, c = 0;
    char selection[0];

    print_menu();

        while((c = getchar()) != EOF)  
        {
            selection[i++] = c;
            selection[i] = '\0';  //insert NULL at end of string
            uppercase(selection);

            switch(selection[i])
            {
                case 'c':
                uppercase(selection);
                printf("%s\n", selection );
                print_menu();
                break;

                case 'X':
                printf("The program is exiting, Schuss!\n" );
                exit(0);

                default:
                printf("\nYou entered: %s\n", selection);
                print_menu();
                break;
           }

        }
 return 0;
}

void print_menu()  //gives code for menu
{
    printf("Select a menu item and hit enter: \n" );
    printf("C)  Convert the string to uppercase\n");
    printf("M)  Display this menu\n");
    printf("X)  Exit the program\n");
}
void uppercase(char *string) 
{
  int c = 0;

  while (string[c] != '\0')
  {
    if (string[c] >= 'a' && string[c] <= 'z')
    {
      string[c] = string[c] - 32;
     }
     c++;
  }

}

如果我在运行程序时输入Yes!,我希望输出是 You entered: Y然后打印菜单。 目前的输出是

You entered: Y
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: YE
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: S
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: S!
Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program

You entered: 

Select a menu item and hit enter: 
C)  Convert the string to uppercase
M)  Display this menu
X)  Exit the program
^C

我很确定这是while 循环的问题,但还没有弄清楚如何解决它。最终我会有更多的菜单项和案例。因此,例如,用户将输入A,它将打印a,然后再次打印菜单以等待下一个菜单选择,直到用户输入“X”退出。另外,我知道uppercase 有两个函数调用,此时这是有意的。

编辑:我希望getchar() 按照设计的方式读取一个字符。然后做任何与该字符的大小写匹配的事情。然后再次打印菜单(这部分包含在每个 case 语句中)。然后从第 1 步开始重复(即“读取一个字符”)。

我更改了我的代码,将getchar() 放在while 循环之外,并将循环设置为while(1),而不是只读取一个字符,但也会创建一个无限循环打印You entered: B 和菜单。这就是进步,有点。

【问题讨论】:

  • char selection[0]; 是错误的。和switch(selection[i]) --> switch(*selection)
  • 我尝试了不同的尺寸,但结果相同。我认为限制数组的大小会起作用,所以保持原样,因为其他大小不起作用。
  • 您想读取用户输入的整行,然后只使用第一个字符。 fgets 适合读取一行输入。
  • 为了便于阅读和理解:1) 一致地缩进代码。仅使用空格进行缩进。 2) 遵循公理:每行只有一个语句,并且(最多)每条语句有一个变量声明。
  • 虽然“隐式转换”可能允许您发布的代码正确运行,但这一行:char i = 0 c = 0; 正在尝试使用int 值初始化几个char 变量。建议使用:= '\0'(一个字符)作为初始化器。

标签: c arrays switch-statement getchar


【解决方案1】:

如何在 C 中用getchar 读取单个字符?

使用getchar,您只能读取单个字符。

我必须要求用户输入,然后在我的程序中只使用输入的第一个字符。

您可以通过读取整行并仅使用该行的第一个字符来做到这一点。

char line[100]; // Make it large enough.
while( fgets(line, 100, stdin) != NULL )
{
    uppercase(line);
    char selection = line[0];

    switch (selection)
    {
       ...
    }
}  

【讨论】:

  • @Rhymoid 如果我能够使用toupper 函数,这种方式可能会很好用。我需要使用自己的 uppercase 函数,这给了我“不兼容的类型”错误。
  • @Rhymoid,哎呀!
  • @InertialOberserver 为什么你不能使用 toupper?如果实在不行的话,自己写toupper函数只要用char类型就容易了(见ASCII表)
  • @Fefux 我确实写了一个类似的函数,因为这是我的任务的一部分。此外,我最终将使用的其他函数也使用与我的“大写”函数相同的格式,因此错误也会在那里弹出。我用于其他函数的格式也是 'void myFunction(char *string)。抱歉我的格式有问题,我遇到了键盘问题。
  • @R Sahu 你说得对,我应该说我想在读取第一个字符后停止读取字符。
【解决方案2】:

如何在 C 中使用 getchar 读取单个字符?

就这样:

getchar();

顺便说一句,你在这里覆盖了一些内存:

char i = 0, c = 0;
char selection[0];  // What?! An array of 0 elements?!

...

    selection[i++] = c;    // Where are you storing the value?
    selection[i] = '\0';   // Same here

请注意,经过一些 while 循环后,您的 i 变量的值将是 12? 34? 1234?,因为在你做selection[i++] = c之前你没有把它初始化为0,每次你都这样做。

【讨论】:

  • 我相信array[0]实际上是一个1的数组,因为[0]是数组第一个元素的位置?我可能是错的,因为我仍在了解数组的工作方式。此外,它似乎确实存储了输入的值,但它并不限制只存储一个我试图通过该设置完成的值。
  • array[0] 导致占位符,数组中没有实际区域
【解决方案3】:

尽管以下代码没有未定义的行为并且允许用户输入最多 128 个字符,但 OPs 代码中没有任何内容,该代码也没有使用前(最多)4 个字符

#include <stdio.h> // getchar(), prinf()
//#include <string.h>
//#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <ctype.h> // toupper()

void print_menu( void );
//void uppercase( char *string ); 

#define MAX_CHARS (128)

int main( void )
{
    size_t i = 0;
    int c;   // getchar() returns an int, not a char
    //char selection[0];
    char selection[ MAX_CHARS+1 ]; // +1 to allow for NUL terminator byte

    print_menu();

    while( i < MAX_CHARS && (c = getchar()) != EOF && 'X' != toupper(c) ) 
    {
        if( '\n' == c )  // ignore any newlines
            continue;

        selection[i++] = (char)toupper(c);
        selection[i] = '\0';  //insert NUL byte at end of string
        //uppercase(selection);

        switch(selection[i-1]) // -1 because 'i' is the termination byte
        {
            //case 'c':
            //    //uppercase(selection);
            //    printf("%s\n", selection );
            //    print_menu();
            //    break;

            //case 'X':
            //    printf("The program is exiting, Schuss!\n" );
            //    //exit(0);
            //    exit( EXIT_SUCCESS );
            //    break;

            default:
                printf("\nYou entered: %s\n", selection);
                print_menu();
                break;
        }
    }

    printf("The program is exiting, Schuss!\n" );
    //return 0; // not needed for 'main()' in modern C
} // end function: main


void print_menu()  //gives code for menu
{
    // note: C concatenates successive literal strings
    printf("Select a menu item and hit enter: \n" 
           "X)  Exit the program\n"
           "any other key appends to input, except newline\n");
} // end function: print_menu


//void uppercase(char *string) 
//{
//  int c = 0;

//  while (string[c] != '\0')
//  {
//    if (string[c] >= 'a' && string[c] <= 'z')
//    {
//      string[c] = string[c] - 32;
//     }
//     c++;
//  }
//}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2010-12-20
    • 1970-01-01
    • 2013-01-03
    相关资源
    最近更新 更多