使用 C 语言中的 getchar 函数
本文将演示关于如何使用 C 语言中的 getchar
函数的多种方法。
在 C 语言中使用 getchar
函数从标准输入流中读取单个字符
getchar
函数是 C 库中标准输入/输出实用程序的一部分。字符输入/输出操作有多个函数,如 fgetc
、getc
、fputc
或 putchar
。fgetc
和 getc
的功能基本相当;它们取文件流指针读取一个字符,并将其以 unsigned char
的形式转换为 int
类型返回。
请注意,getchar
是 getc
的特殊情况,它隐含地传递了 stdin
文件流作为参数来读取字符。因此,getchar
不需要任何参数,并将读取的字符转换为 int
类型返回。在下面的例子中,我们演示了用 putchar
函数输入一个字符并打印的基本情况。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
printf("Please, input a single character: ");
ch = getchar();
putchar(ch);
exit(EXIT_SUCCESS);
}
在 C 语言中使用 getchar
函数读取字符串输入
或者,我们可以实现一个循环来读取输入的字符串,直到遇到新的行或 EOF
,并将其存储在一个预先分配的 char
缓冲区。不过要注意,与调用 gets
或 getline
相比,这种方法会增加性能开销,而 gets
或 getline
是实现同样功能的库函数。解决方案的主要部分是一个 while
循环,执行到 getchar
函数返回的值不等于新的行字符或 EOF
。
在这种情况下,我们任意分配一个大小为 20 个字符的 char
数组。每一次迭代,都会实现数组中第一个元素的指针,并将 getchar
的返回值分配给它。最后,我们用 printf
函数调用输出缓冲区。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void)
{
char buf[SIZE];
char *p;
int ch;
p = buf;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
*p++ = (char)ch;
}
*p++ = 0;
if (ch == EOF) {
printf("EOF encountered\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
输出:
Please, provide input: string longer than 20 characters
string longer than 20 characters
尽管前面的例子代码通常都能正常工作,但它有几个错误,可能导致缓冲区溢出错误或程序异常终止。由于我们处理用户输入的内容直到遇到新的行或 EOF
,所以不能保证它能装进固定大小的 char
缓冲区。如果我们必须使用固定缓冲区,我们要负责统计输入的大小,并在达到容量后停止在缓冲区中存储。
在前面的代码中我们解决了这个问题后,我们要处理使用%s
指定符打印缓冲区内容的 printf
语句。需要注意的是,并不能保证输入字符串的最后一个字符是空字节,所以如果用户自己没有在缓冲区的最后插入空字节,printf
调用就不知道停在哪里。下面的示例代码纠正了之前的错误,并增加了一些行数,以便更好的演示。
#include <stdio.h>
#include <stdlib.h>
enum { SIZE = 20 };
int main(void)
{
char buf[SIZE];
int ch;
size_t index = 0;
size_t chars_read = 0;
printf("Please, provide input: ");
while ((ch = getchar()) != '\n' && ch != EOF) {
if (index < sizeof(buf) - 1) {
buf[index++] = (char)ch;
}
chars_read++;
}
buf[index] = '\0';
if (ch == EOF) {
printf("EOF encountered\n");
}
if (chars_read > index) {
printf("Truncation occured!\n");
}
printf("%s\n", buf);
exit(EXIT_SUCCESS);
}
输出:
Please, provide input: string longer than 20 characters
Truncation occured!
string longer than
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn