C语言输入输出函数完整指南:从基础到高级应用
前言
在C语言编程中,输入输出(I/O)操作是最基础也是最重要的部分。无论是简单的"Hello World"程序还是复杂的系统应用,都离不开I/O操作。本文将全面介绍C语言中的各种输入输出函数,包括它们的特点、使用场景和最佳实践。
目录
前言
一、字符输入输出函数
1.1 putchar() - 字符输出
1.2 getchar() - 字符输入
二、字符串输入输出函数
2.1 puts() - 字符串输出
2.2 fputs() - 文件字符串输出
2.3 字符串输入函数对比
gets() - 不安全的字符串输入(已废弃)
fgets() - 安全的字符串输入(推荐)
三、格式化输入输出函数
3.1 printf() - 格式化输出
常用格式说明符
格式修饰符
3.2 scanf() - 格式化输入
空格处理问题及解决方案
%*c 的妙用
四、文件输入输出函数
4.1 文件写入操作
4.2 文件读取操作
五、输入输出函数综合对比
六、最佳实践和实用技巧
6.1 安全的输入函数封装
6.2 混合使用输入函数的注意事项
七、总结
一、字符输入输出函数
1.1 putchar() - 字符输出
putchar() 是最简单的字符输出函数,用于向标准输出(通常是屏幕)输出单个字符。
函数原型:
c
int putchar(int c);
使用示例:
c
#include <stdio.h>int main() {putchar('A'); // 输出字符 Aputchar('\n'); // 输出换行符putchar(65); // 输出 ASCII 码 65 对应的字符 A// 输出字符串(逐个字符)char str[] = "Hello";for(int i = 0; str[i] != '\0'; i++) {putchar(str[i]);}putchar('\n');return 0;
}
输出结果:
text
A
A
Hello
1.2 getchar() - 字符输入
getchar() 用于从标准输入读取单个字符。
函数原型:
c
int getchar(void);
使用示例:
c
#include <stdio.h>int main() {char ch;printf("请输入一个字符: ");ch = getchar();printf("你输入的字符是: ");putchar(ch);putchar('\n');return 0;
}
二、字符串输入输出函数
2.1 puts() - 字符串输出
puts() 用于输出字符串,并自动在末尾添加换行符。
函数原型:
c
int puts(const char *str);
使用示例:
c
#include <stdio.h>int main() {char str[] = "Hello World";puts(str); // 输出后自动换行puts("Another line"); // 不需要手动加\nreturn 0;
}
输出结果:
text
Hello World
Another line
2.2 fputs() - 文件字符串输出
fputs() 用于向指定文件流输出字符串,不会自动添加换行符。
函数原型:
c
int fputs(const char *str, FILE *stream);
使用示例:
c
#include <stdio.h>int main() {fputs("Hello ", stdout);fputs("World", stdout);fputs("\n", stdout); // 需要手动换行return 0;
}
2.3 字符串输入函数对比
gets() - 不安全的字符串输入(已废弃)
c
#include <stdio.h>int main() {char str[100];printf("输入字符串: ");gets(str); // 危险!不检查缓冲区边界printf("你输入: %s\n", str);return 0;
}
fgets() - 安全的字符串输入(推荐)
c
#include <stdio.h>
#include <string.h>// 移除字符串末尾的换行符
void remove_newline(char *str) {int len = strlen(str);if (len > 0 && str[len-1] == '\n') {str[len-1] = '\0';}
}int main() {char str[100];printf("输入字符串: ");fgets(str, sizeof(str), stdin); // 安全,指定最大长度remove_newline(str); // 移除换行符printf("你输入: %s\n", str);printf("字符串长度: %zu\n", strlen(str));return 0;
}
三、格式化输入输出函数
3.1 printf() - 格式化输出
printf() 是C语言中最常用的输出函数,支持复杂的格式化输出。
基本格式:
c
int printf(const char *format, ...);
常用格式说明符
| 格式符 | 说明 | 示例 |
|---|---|---|
%d | 有符号十进制整数 | printf("%d", 123) |
%u | 无符号十进制整数 | printf("%u", 123u) |
%f | 浮点数 | printf("%f", 3.14) |
%c | 字符 | printf("%c", 'A') |
%s | 字符串 | printf("%s", "hello") |
%p | 指针地址 | printf("%p", &var) |
%x | 十六进制整数 | printf("%x", 255) |
格式修饰符
c
#include <stdio.h>int main() {int num = 123;float pi = 3.14159;char ch = 'A';char str[] = "Hello";// 宽度和对齐printf("数字: |%5d|\n", num); // 右对齐,宽度5printf("数字: |%-5d|\n", num); // 左对齐,宽度5printf("数字: |%05d|\n", num); // 用0填充// 浮点数精度printf("PI: %.2f\n", pi); // 保留2位小数printf("PI: %8.3f\n", pi); // 总宽度8,3位小数// 字符串截断printf("字符串: %.3s\n", str); // 只输出前3个字符return 0;
}
输出结果:
text
数字: | 123|
数字: |123 |
数字: |00123|
PI: 3.14
PI: 3.142
字符串: Hel
3.2 scanf() - 格式化输入
scanf() 用于从标准输入读取格式化数据。
基本格式:
c
int scanf(const char *format, ...);
空格处理问题及解决方案
问题示例:
c
#include <stdio.h>int main() {char str[100];printf("输入字符串: ");scanf("%s", str); // 遇到空格会停止读取printf("你输入的是: %s\n", str);return 0;
}
运行结果:
text
输入: Hello World
输出: Hello (只读取了第一个单词)
解决方案:
c
#include <stdio.h>int main() {char str[100];// 方法1: 使用扫描集读取包含空格的字符串printf("输入包含空格的字符串: ");scanf("%[^\n]", str); // 读取直到遇到换行符printf("方法1: %s\n", str);// 清空输入缓冲区while (getchar() != '\n');// 方法2: 限制读取长度printf("再次输入: ");scanf("%99[^\n]", str); // 最多读取99个字符printf("方法2: %s\n", str);return 0;
}
%*c 的妙用
%*c 在 scanf() 中用于读取并丢弃一个字符,常用于跳过不需要的字符或清空缓冲区。
应用场景1:跳过特定字符
c
#include <stdio.h>int main() {int day, month, year;printf("输入日期(DD-MM-YYYY): ");scanf("%d-%d-%d", &day, &month, &year);printf("日期: %d/%d/%d\n", day, month, year);return 0;
}
应用场景2:清除缓冲区中的换行符
c
#include <stdio.h>int main() {int num;char ch;printf("输入一个数字: ");scanf("%d", &num);// 清除数字后面的换行符scanf("%*c");printf("输入一个字符: ");scanf("%c", &ch);printf("数字: %d, 字符: %c\n", num, ch);return 0;
}
应用场景3:混合输入时的缓冲区管理
c
#include <stdio.h>int main() {int age;char name[50];printf("输入年龄: ");scanf("%d", &age);// 清除缓冲区中剩余的所有字符,直到换行符scanf("%*[^\n]"); // 读取并丢弃换行符之前的所有字符scanf("%*c"); // 读取并丢弃换行符本身printf("输入姓名: ");scanf("%49[^\n]", name); // 安全读取包含空格的姓名printf("年龄: %d, 姓名: %s\n", age, name);return 0;
}
四、文件输入输出函数
4.1 文件写入操作
c
#include <stdio.h>int main() {FILE *file = fopen("example.txt", "w");if (file != NULL) {fputc('A', file); // 写入单个字符fputs("Hello File\n", file); // 写入字符串fprintf(file, "Number: %d\n", 123); // 格式化写入fclose(file);printf("文件写入成功!\n");} else {printf("文件打开失败!\n");}return 0;
}
4.2 文件读取操作
c
#include <stdio.h>int main() {FILE *file = fopen("example.txt", "r");if (file != NULL) {int ch;printf("文件内容:\n");while ((ch = fgetc(file)) != EOF) {putchar(ch);}fclose(file);} else {printf("文件打开失败!\n");}return 0;
}
五、输入输出函数综合对比
| 函数 | 类型 | 特点 | 安全性 | 推荐程度 |
|---|---|---|---|---|
putchar() | 字符输出 | 简单高效 | 安全 | ⭐⭐⭐⭐ |
getchar() | 字符输入 | 简单 | 安全 | ⭐⭐⭐⭐ |
puts() | 字符串输出 | 自动换行 | 安全 | ⭐⭐⭐⭐ |
fputs() | 字符串输出 | 不自动换行 | 安全 | ⭐⭐⭐ |
printf() | 格式化输出 | 功能强大 | 安全 | ⭐⭐⭐⭐⭐ |
scanf() | 格式化输入 | 功能强大 | 需谨慎使用 | ⭐⭐⭐ |
gets() | 字符串输入 | 已废弃 | 危险 | ⭐ |
fgets() | 字符串输入 | 安全可靠 | 安全 | ⭐⭐⭐⭐⭐ |
六、最佳实践和实用技巧
6.1 安全的输入函数封装
c
#include <stdio.h>
#include <string.h>
#include <ctype.h>// 清空输入缓冲区
void clear_input_buffer() {int c;while ((c = getchar()) != '\n' && c != EOF);
}// 安全的字符串输入
int safe_string_input(char *buffer, int size, const char *prompt) {printf("%s", prompt);if (fgets(buffer, size, stdin) == NULL) {return -1; // 读取失败}// 移除换行符size_t len = strlen(buffer);if (len > 0 && buffer[len-1] == '\n') {buffer[len-1] = '\0';return len - 1;}// 如果缓冲区已满但还有输入,清空剩余输入if (len == size - 1) {clear_input_buffer();}return len;
}// 安全的整数输入
int safe_int_input(const char *prompt) {char buffer[100];int number;while (1) {safe_string_input(buffer, sizeof(buffer), prompt);if (sscanf(buffer, "%d", &number) == 1) {return number;}printf("输入无效,请重新输入!\n");}
}int main() {char name[50];int age;safe_string_input(name, sizeof(name), "请输入姓名: ");age = safe_int_input("请输入年龄: ");printf("\n姓名: %s\n", name);printf("年龄: %d\n", age);return 0;
}
6.2 混合使用输入函数的注意事项
c
#include <stdio.h>int main() {int num1, num2;char ch;char str[100];// 正确的混合输入方式printf("输入第一个数字: ");scanf("%d", &num1);clear_input_buffer(); // 清除换行符printf("输入一个字符: ");scanf("%c", &ch);clear_input_buffer(); // 清除换行符printf("输入字符串: ");fgets(str, sizeof(str), stdin);// fgets会保留换行符,需要处理printf("输入第二个数字: ");scanf("%d", &num2);printf("数字1: %d, 字符: %c, 字符串: %s, 数字2: %d\n", num1, ch, str, num2);return 0;
}
七、总结
C语言提供了丰富的输入输出函数,每种函数都有其特定的使用场景:
-
字符I/O:
putchar()、getchar()简单高效 -
字符串I/O:优先使用
fgets()和fputs(),避免使用不安全的gets() -
格式化I/O:
printf()功能强大,scanf()需要谨慎处理空格和缓冲区 -
文件I/O:使用文件流版本的函数进行文件操作
关键建议:
-
始终使用
fgets()进行字符串输入 -
使用
scanf()时限制输入长度并处理空格问题 -
混合使用不同输入函数时要妥善管理输入缓冲区
-
封装安全的输入函数以提高代码的健壮性
掌握这些输入输出函数的正确使用方法,能够帮助你编写出更加安全、可靠的C语言程序。
