目录
程序运行时,需打印信息至标准输出 stdout 设备 或标准错误 stderr设备(譬如屏幕),如调试信息、报错信息、中间产生的变量的值等,以监控和分析状态。同时,程序还需从stdin(如键盘)读取并解析字符串。
1 字符串输出
1.1 字符串输出函数简介
常用的字符串输出函数有 printf()、putchar()、 puts()、 fputc()、 fputs()。我们经常使用 printf()函数来输出字符串信息,而并没有使用到 putchar()、 puts()、 fputc()、 fputs()这些函数,原因在于printf()可以按照自己规定的格式输出字符串信息,一般称为格式化输出;而 putchar()、 puts()、 fputc()、 fputs()这些函数只能输出字符串,不能进行格式转换。
与 printf()一样, putchar()、 puts()、 fputc()、 fputs()这些函数也是标准 I/O 函数, 属于标准 C 库函数, 所以需要包含头文件<stdio.h>,并且它们也使用 stdio 缓冲。
putchar()
、puts()
、fputc()
和 fputs()
是用于输出字符串的基本函数,它们的特点如下:
putchar()
用来输出单个字符。puts()
用于输出一个字符串,并且会在字符串末尾自动添加换行符。fputc()
功能类似于putchar()
,但它可以指定输出到任意文件流,而不仅仅是标准输出。fputs()
则用于向指定的文件流输出字符串,不会自动添加换行符。
函数的原型如下:
#include <stdio.h>
int putchar(int c); // 输出单个字符 c 到 stdout
int puts(const char *s); // 输出字符串 s 到 stdout,并在末尾添加换行符
int fputc(int c, FILE *stream); // 将字符 c 输出到指定的文件流 stream
int fputs(const char *s, FILE *stream); // 将字符串 s 输出到指定的文件流 stream
1.2 示例程序
#include <stdio.h>
int main()
{
char greeting[] = "Hello, World!";
char name[] = "Linux";
// 使用 puts 输出字符串,末尾自动添加换行符
puts(greeting);
// 使用 putchar 输出单个字符,每次调用输出一个字符
putchar('H');
putchar('i');
putchar('\n');
// 使用 fputc 输出单个字符到标准错误流 stderr
fputc('!', stderr);
// 使用 fputs 输出字符串到标准输出流 stdout,不自动添加换行符
fputs("Put: ", stdout);
fputs(name, stdout);
putchar('\n'); // 手动添加换行符
return 0;
}
使用 puts()
输出了一个字符串 "Hello, World!",然后使用 putchar()
分别输出了 "Hi" 和换行符。接着使用 fputc()
将字符 '!' 输出到了标准错误流 stderr
。最后使用 fputs()
输出了 "Kimi says: " 和字符串 "Kimi",然后手动添加了一个换行符。运行结果如下:
2 字符串输入
2.1 字符串输入简介
常用的字符串输入函数有 gets()、 getchar()、 fgetc()、 fgets()。与 printf()对应, 在 C 库函数中同样也提供了格式化输入函数 scanf()。 scanf()与 gets()、 getchar()、 fgetc()、 fgets()这些函数相比,在功能上确实有它的优势,但是在使用上不如它们方便、简单、更易于使用。
与 scanf()一样, gets()、 getchar()、 fgetc()、 fgets()这些函数也是标准 I/O 函数, 属于标准 C 库函数, 所以需要包含头文件<stdio.h>,并且它们也使用 stdio 缓冲。
gets()、 getchar()、 fgetc()、 fgets()的特点如下:
gets()
函数是不安全的,因为它不检查目标缓冲区的大小,可能会导致缓冲区溢出。因此,它已经被废弃,不推荐使用。作为替代,应该使用fgets()
。getchar()
函数用于从标准输入读取单个字符。fgetc()
函数用于从指定的文件流读取单个字符,通常用于标准输入。fgets()
函数用于从指定的文件流读取一行数据,最多读取size-1
个字符,并将结果存储在字符串s
中。它在读取到换行符时会将其存储在缓冲区中,但不会输出到stdout
。
函数原型如下:
char *gets(char *s); // 从 stdin 读取一行数据到字符串 s,直到遇到换行符或 EOF,不推荐使用,已废弃
int getchar(void); // 从 stdin 读取下一个字符
int fgetc(FILE *stream); // 从指定的文件流 stream 读取下一个字符
char *fgets(char *s, int size, FILE *stream); // 从指定的文件流 stream 读取最多 size-1 个字符到字符串 s,直到遇到换行符、EOF 或最大字符数限制
2.2 示例程序
#include <stdio.h>
#include <string.h>
int main() {
char buffer[100];
char ch;
// 使用 getchar() 读取单个字符
printf("Press a key: ");
ch = getchar(); // 读取单个字符
// 清除换行符
while (getchar() != '\n') continue; // 循环直到遇到换行符
printf("You pressed: %c\n", ch);
// 使用 fgets() 读取一行文本
printf("Enter a sentence: ");
fgets(buffer, sizeof(buffer), stdin); // 读取一行文本
// 去除末尾的换行符
if (buffer[strlen(buffer) - 1] == '\n') {
buffer[strlen(buffer) - 1] = '\0';
}
printf("You entered: %s\n", buffer);
// 使用 fgetc() 读取单个字符
printf("Press another key: ");
ch = fgetc(stdin); // 读取单个字符
// 清除换行符
while (getchar() != '\n') continue; // 清除换行符
printf("You pressed again: %c\n", ch);
return 0;
}
程序演示了如何使用 getchar()
、fgets()
和 fgetc()
函数从标准输入读取数据。
- 程序首先提示用户按下一个键,并使用
getchar()
读取这个按键字符,然后清除输入缓冲区中的换行符,并输出用户按下的字符。 - 接着,程序提示用户输入一行文本,使用
fgets()
读取并存储到buffer
数组中,同时去除末尾的换行符(如果存在),然后输出用户输入的文本。 - 最后,程序再次提示用户按下另一个键,使用
fgetc()
读取这个按键字符,清除随后的换行符,并输出用户再次按下的字符。
程序的运行结果如下: