scanf,priintf。注意%格式使用!

本文深入探讨了C语言中`scanf`和`printf`函数的使用细节,包括如何通过输入和输出参数实现更高效的数据交互。特别强调了通过合理设置格式控制符来优化输入输出体验,如利用`%d`与空格分隔输入多个整数,以及`%-3d`和`%12d`等特殊格式控制符实现的左对齐和右对齐效果。此外,文章还详细解释了如何灵活运用这些功能来处理不同长度的数据输入输出需求。
scanf 输入多个整形字符时,若想让输入时用空格分隔字符,则%d%d之间不需要任何字符,默认表示空白字符。
除此外输入格式和scanf里%d%d的格式一致。

printf输出多个整形字符时,若想让输出时用空格分隔则
%d %d之间必须有空格。输出格式和printf里%d%d的格
一致。

%-3d  表示向左对齐,占3位;
%12d 表示向右对齐,占12位。
故由上可得,整数向右对齐,负数向左对齐,数字占多少位

你提到的这三行 `scanf` 调用: ```c scanf("%c", &c); scanf("%d", &i); scanf("%s", s); ``` 是 C 语言中常见的输入方式,但它们的行为有**重要的细节差异和潜在陷阱**,尤其是在处理空白字符(如空格、换行)时。下面我将详细解释每一句的作用、常见问题以及如何正确使用。 --- ### ✅ 回答问题:逐条解释 #### 1. `scanf("%c", &c);` - **功能**:读取**下一个字符**,包括空格、制表符 `\t`、换行符 `\n`。 - **特点**: - 不会跳过任何空白字符。 - 如果输入缓冲区中有残留的换行符(例如前一个输入留下的 `\n`),它会立即读取这个 `\n`,导致“意外”行为。 > 🔍 示例: > > 输入: > ``` > A<Enter> > ``` > 执行后 `c = 'A'` > 但如果前面有一次 `scanf("%d")` 后按了回车,那么这次 `%c` 可能读到的是那个回车符 `\n`! --- #### 2. `scanf("%d", &i);` - **功能**:读取一个整数。 - **特点**: - 会自动**跳过开头的所有空白字符**(空格、`\t`、`\n`)直到遇到数字。 - 停止在第一个非数字字符(比如换行或字母),该字符仍留在输入流中。 > 📌 举例: > > 输入:` 123abc` > > - 成功读取 `i = 123` > - `'a'` 留在缓冲区,可能被后续 `scanf("%c")` 读走 --- #### 3. `scanf("%s", s);` - **功能**:读取一个字符串(无空格的单词)。 - **特点**: - 跳过开头的空白字符(空格、换行等) - 从第一个非空白字符开始读取 - 在遇到下一个空白字符(空格、换行、制表符)时停止 - **不会检查数组边界** → 容易造成缓冲区溢出! > ⚠️ 危险示例: > > ```c > char s[5]; > scanf("%s", s); // 输入 "hello world" → 至少写入6字节(含'\0')→ 溢出! > ``` --- ### ⚠️ 经典问题:顺序执行这三个语句会发生什么? 假设代码如下: ```c char c; int i; char s[100]; scanf("%c", &c); scanf("%d", &i); scanf("%s", s); ``` 用户输入: ``` A 123 hello ``` 结果分析: 1. `scanf("%c", &c)` → 读取 `'A'` 2. 接着按下回车 → 缓冲区留下 `'\n'` 3. `scanf("%d", &i)` → 自动跳过 `\n`,等待输入 → 用户输入 `123` + 回车 → 正确读取 4. `scanf("%s", s)` → 跳过换行,读取 `hello` ✅ 运行正常。 --- ### ❌ 但如果输入在同一行或顺序混乱呢? 例如输入: ``` A 123 hello ``` 则: - `%c` → 读 `'A'` - `%d` → 跳过空格,读 `123` - `%s` → 跳过空格,读 `hello` ✅ 仍然可以工作。 但若这样输入: ``` A 123 hello ``` 也 OK,因为 `%d` 和 `%s` 都会自动跳过空白。 --- ### 💥 真正危险的情况:混合使用 `%c` 和其他格式 最常见的 bug 是: ```c scanf("%d", &i); scanf("%c", &c); // 你以为是在等你输入一个字符? ``` 用户输入:`123<Enter>` - 第一个 `scanf` 读 `123` - 第二个 `scanf` 直接读走了 `<Enter>` 对应的 `'\n'`! - 用户根本没机会输入字符! --- ### ✅ 解决方法:清理输入缓冲区或控制空白 #### 方法一:在 `%c` 前加空格(推荐) ```c scanf(" %c", &c); // 注意前面有个空格! ``` - 这个空格表示“忽略所有前导空白字符” - 就不会读到 `\n`、`\t`、空格等 #### 方法二:手动清空输入缓冲区(不跨平台) ```c int ch; while ((ch = getchar()) != '\n' && ch != EOF); ``` --- ### ✅ 更安全的字符串输入替代方案 避免使用 `scanf("%s", s)`,改用: ```c scanf("%99s", s); // 限制最大读取长度(防止溢出) ``` 或者更安全的方式: ```c fgets(s, sizeof(s), stdin); // 推荐用于读字符串 ``` 注意:`fgets` 会保留换行符 `\n`,需要手动去除。 --- ### ✅ 推荐改进代码模板: ```c #include <stdio.h> #include <string.h> int main() { char c; int i; char s[100]; printf("请输入一个字符: "); scanf(" %c", &c); // 注意空格! printf("请输入一个整数: "); scanf("%d", &i); printf("请输入一个字符串: "); scanf("%99s", s); // 防止溢出 printf("字符: %c\n整数: %d\n字符串: %s\n", c, i, s); return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值