鱼C论坛

 找回密码
 立即注册
楼主: 11063216906

[已解决]浮点数存取问题

[复制链接]
 楼主| 发表于 2026-9-1 21:23:16 | 显示全部楼层
FishC 发表于 2026-9-1 21:14
scanf 和 getchar 搭配使用,最常见的目的就是**清理输入缓冲区中残留的换行符**。

先看典型问题:  ...

我编写完程序如何用gcc进行compile输出.c文件
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 21:23:26 | 显示全部楼层
11063216906 发表于 2026-09-01 21:23
FishC 发表于 2026-9-1 21:14
scanf 和 getchar 搭配 ...


你的理解有点小误会:gcc 不会“输出 .c 文件”,因为 .c 是**源代码文件**,是给编译器读的输入。gcc 的输出一般是**可执行文件**(比如 a.out)或**目标文件**(.o 文件)。

如果你想用 gcc 编译你的 .c 源文件,常见的用法如下:

- 生成可执行文件(最常用):  
  1. gcc 你的程序.c -o 你的程序
复制代码

例如:  
  1. gcc hello.c -o hello
复制代码

执行时用:  
  1. ./hello
复制代码


- 只编译不链接,生成目标文件(.o 文件):  
  1. gcc -c 你的程序.c -o 你的程序.o
复制代码

例如:  
  1. gcc -c hello.c -o hello.o
复制代码

这样会生成 hello.o,它还不能直接运行,需要最后链接成可执行文件。

所以,如果你想要一个“输出文件”,请明确是想要可执行文件还是 .o 文件。gcc 永远不会把 .c 文件变成另一个 .c 文件,那是没有意义的事情。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 21:41:27 | 显示全部楼层
FishC 发表于 2026-9-1 21:14
scanf 和 getchar 搭配使用,最常见的目的就是**清理输入缓冲区中残留的换行符**。

先看典型问题:  ...

是我对scanf理解有误区吗 scanf不是直接读取用户输入的东西然后赋值给num吗
下面ch = getchar()在干嘛
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 21:41:32 | 显示全部楼层
11063216906 发表于 2026-09-01 21:41
FishC 发表于 2026-9-1 21:14
scanf 和 getchar 搭配 ...


你的理解基本正确,但缺少一个关键细节:**scanf 只读取符合格式的内容,不会“吃掉”输入中多余的字符**。

比如你输入:  
123 然后按回车,  
缓冲区里实际是:  
123\n

scanf("%d", &num) 会读取数字 123 并存入 num,**但那个 \n 仍然留在缓冲区里**。

紧接着执行 ch = getchar() 时,getchar 发现缓冲区里已经有一个 **\n**,于是立刻把它读走,赋给 ch。此时 ch 的值就是换行符,而不是你接下来想输入的字符。

所以搭配使用时,常见写法是:


  1. int num;
  2. char ch;

  3. scanf("%d", &num);
  4. getchar();               // 吃掉残留的换行符
  5. ch = getchar();          // 此时才真正等待用户输入新字符
复制代码


如果不用 getchar 清理,也可以让 scanf 自己跳过空白字符:


  1. scanf("%d ", &num);      // 注意 %d 后面有个空格
  2. ch = getchar();          // 直接读取新字符
复制代码


简单说:scanf 负责“取数据”,getchar 负责“清尾巴”。你理解 scanf 没错,只是别忘了它会把回车留下。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 21:42:43 | 显示全部楼层
FishC 发表于 2026-9-1 21:41
你的理解基本正确,但缺少一个关键细节:**scanf 只读取符合格式的内容,不会“吃掉”输入中多余的字符 ...

getchar()本身是干什么用的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 21:42:50 | 显示全部楼层
11063216906 发表于 2026-09-01 21:42
FishC 发表于 2026-9-1 21:41
你的理解基本正确,但 ...


getchar() 是 C 标准库中的一个输入函数,它的作用是从标准输入(通常是键盘)读取【一个字符】。每次调用它,程序都会尝试从输入缓冲区中取走一个字符,并返回该字符的 ASCII 码值。

具体特点:
- 一次只读取一个字符,不会一次读一串。
- 如果缓冲区中没有字符,程序会暂停,等待你输入并按下回车键。
- 返回值类型是 int,这样可以正确表示 EOF(文件结束标志,值为 -1)。

简单来说,getchar() 就是“读单个字符”的工具。它既可以用来读取字符,也可以用来清掉输入缓冲区中残留的换行符。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 21:51:23 | 显示全部楼层
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.         int num;
  5.         scanf("enter your number : %d" ,&num);
  6.         printf("im here");
  7.         printf("%d" , &num);
  8.         printf("imhere2");
  9.         char ch1 = getchar();
  10.         printf("before ch1");
  11.         printf("%c" , &ch1);
  12.         printf("ch1")
  13.         char ch2 = getchar();
  14.         printf("%c" , &ch2);


复制代码


我ch1的getchar为什么没有反应不被执行
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 21:51:38 | 显示全部楼层
11063216906 发表于 2026-09-01 21:51
#include <stdio.h>

int main(void)
{
        i ...


我来帮你分析为什么 `ch1` 的 `getchar()` 没有等待输入,而是直接“跳过”了。


  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int num;
  5.     scanf("enter your number : %d", &num);
  6.     printf("im here");
  7.     printf("%d", &num);      // 这里错了,应该用 num,不是 &num
  8.     printf("imhere2");

  9.     char ch1 = getchar();
  10.     printf("before ch1");
  11.     printf("%c", &ch1);      // 这里也错了,应该用 ch1,不是 &ch1
  12.     printf("ch1");            // 少了分号

  13.     char ch2 = getchar();
  14.     printf("%c", &ch2);
  15.     return 0;
  16. }
复制代码


先说你最关心的问题:  
你输入数字后按了回车,此时输入缓冲区里是:  
123\n  
scanf("%d", &num) 只把 123 取走,留下了 \n(换行符)。  
接下来 ch1 = getchar() 发现缓冲区里已经有一个 \n,所以它**不会等待你输入新字符**,而是立刻把这个换行符读走,赋值给 ch1。  
因此程序看起来像“没有反应”,其实它已经执行了,只是读到了回车符。

另外,你的 scanf 格式字符串写成了:  
"enter your number : %d"  
这会导致 scanf 要求你输入的内容里必须包含 enter your number : 这串普通字符,否则匹配失败。通常提示语应该用 printf 输出,而不是写进 scanf 的格式串里。

正确写法大致是:


  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int num;
  5.     char ch1, ch2;

  6.     printf("enter your number : ");
  7.     scanf("%d", &num);
  8.     getchar();            // 吃掉残留的换行符
  9.     ch1 = getchar();      // 现在才会真正等待你的新输入
  10.     getchar();            // 如果还要读下一个字符,记得再清掉前一个回车

  11.     printf("num = %d\n", num);
  12.     printf("ch1 = %c\n", ch1);
  13.     return 0;
  14. }
复制代码


总结:  
- getchar() 不是“没执行”,而是立刻读走了 scanf 留下的回车符。  
- 想让它暂停等待,需要先用 getchar() 清掉那个换行符,再用第二个 getchar() 读取新输入。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 21:54:43 | 显示全部楼层
FishC 发表于 2026-9-1 21:51
我来帮你分析为什么 `ch1` 的 `getchar()` 没有等待输入,而是直接“跳过”了。

那ch1读走了\n
为啥ch2不执行呢 缓冲区不是没有东西了吗 为啥不让我输入
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 21:54:54 | 显示全部楼层
11063216906 发表于 2026-09-01 21:54
FishC 发表于 2026-9-1 21:51
我来帮你分析为什么 `c ...


你的 `ch2 = getchar();` 其实**已经执行了**,只是它在等待你输入新字符,但由于前面没有 `printf` 给出提示,你感觉不到它在等你。另外,如果缓冲区里还有残留字符,它也会直接读走,不会等待。

关键点:

- `ch1` 读走 `\n` 后,缓冲区确实空了,此时 `ch2 = getchar();` 会阻塞等待你输入一个字符并回车。
- 但你代码里 `ch2 = getchar();` 前后都没有打印提示,所以屏幕看起来像卡住/没执行,实际上它在等你输入。
- 如果你在 `ch2 = getchar();` 前加一句 `printf("please input: ");`,就能明显看到程序暂停等待了。

还有你代码里的几个问题:
- `printf("%d", &num);` 应改成 `printf("%d", num);`
- `printf("%c", &ch1);` 应改成 `printf("%c", ch1);`
- `printf("ch1")` 少了分号,会导致编译错误。

另外,`scanf("enter your number : %d", &num);` 这种写法很危险,它要求输入里必须包含 `enter your number :` 这些字才能匹配成功。建议改成:


printf("enter your number : ");
scanf("%d", &num);


这样更符合常规用法。`ch2` 不是不执行,而是你感受不到它在等待,加个提示就清楚了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 22:00:01 | 显示全部楼层
FishC 发表于 2026-9-1 21:54
你的 `ch2 = getchar();` 其实**已经执行了**,只是它在等待你输入新字符,但由于前面没有 `printf` 给 ...

这种写法很危险,它要求输入里必须包含 `enter your number :` 这些字才能匹配成功。建议改成:
请详细解释下这个事情
还有 我加了提示语我发现ch2还是不等待啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 22:00:16 | 显示全部楼层
11063216906 发表于 2026-09-01 22:00
FishC 发表于 2026-9-1 21:54
你的 `ch2 = getchar() ...


关于 scanf 格式字符串中的普通字符,确实存在一个大坑。

scanf("enter your number : %d", &num); 这个格式串里,除了 %d 以外,其他所有字符(包括空格、冒号、字母)都要求输入流中**逐字匹配**。也就是说,你运行程序后,必须完整输入:

enter your number : 123

然后按回车,scanf 才能成功读取到 123 并赋值给 num。如果你只输入 123 回车,那么 scanf 在比较第一个字符 '1' 和格式串中的 'e' 时就不匹配,匹配立刻失败,num 不会被赋值,整个输入流中的 123\n 全部原封不动地留在缓冲区里。

这很“危险”的原因就是:用户的输入稍有不符,scanf 就罢工,而缓冲区里的残留字符会“污染”后续的 getchar() 等输入函数。

现在说说你的 ch2 为什么不等待。如果你没有成功匹配 scanf,缓冲区里可能有 123\n(或者你乱七八糟输入的一串字符)。然后:

- ch1 = getchar(); 会立刻读走第一个字符,比如 '1'
- ch2 = getchar(); 又会立刻读走下一个字符,比如 '2'

所以 ch2 根本等不到你敲键盘,因为缓冲区里还有存货。即使你加了提示语,getchar 发现有字符可读,它也不会等待,直接拿走下一个字符。

正确做法是:提示语用 printf 输出,scanf 只放格式符。


  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int num;
  5.     char ch1, ch2;

  6.     printf("enter your number : ");
  7.     scanf("%d", &num);

  8.     // 清掉 scanf 留在缓冲区里的换行符
  9.     getchar();

  10.     printf("before ch1\n");
  11.     ch1 = getchar();
  12.     printf("ch1 = %c\n", ch1);

  13.     printf("before ch2\n");
  14.     ch2 = getchar();
  15.     printf("ch2 = %c\n", ch2);

  16.     return 0;
  17. }
复制代码


这样每次 getchar() 都能有明确等待效果。记住:scanf 格式串中不要夹杂提示文字,那只会给你自己挖坑。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 22:05:54 | 显示全部楼层
FishC 发表于 2026-9-1 22:00
关于 scanf 格式字符串中的普通字符,确实存在一个大坑。

scanf("enter your number : %d", &num);  ...

能给我介绍下缓冲区吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 22:06:02 | 显示全部楼层
11063216906 发表于 2026-09-01 22:05
FishC 发表于 2026-9-1 22:00
关于 scanf 格式字符串 ...


缓冲区(Buffer)是计算机中一块临时存储数据的内存区域,用来协调数据的生产和消费速度不匹配的问题。简单说,就是“先攒着,再一起处理”。

具体到C语言的输入输出:

- 键盘输入默认是“行缓冲”的。你输入内容后,系统先把字符存在缓冲区里,当你按下回车键时,才把整行数据交给程序使用。
- printf 输出时,也可能先写入缓冲区,等缓冲区满了、程序结束、或者强制刷新时才真正显示到屏幕上。

常见问题:

输入缓冲区里残留字符会导致 getchar() 不等待,直接读走旧数据。例如:
scanf("%d", &num); // 输入 123 回车,缓冲区中是 123\n,scanf 只取走 123,留下 \n
getchar();        // 这个 getchar 会立刻读走残留的 \n

清空缓冲区的一种常用方法:
while (getchar() != '\n'); // 一直读,直到把换行符也读掉

缓冲区的种类:

- 全缓冲:数据填满缓冲区才进行实际读写(如文件读写)。
- 行缓冲:遇到换行符才进行实际读写(如终端输入)。
- 无缓冲:立即读写(如标准错误输出 stderr)。

缓冲区的好处是减少频繁的I/O操作,提高程序运行效率。但也会带来“看似卡住”或“输入顺序错乱”的困扰,理解它就能避免很多坑。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2026-9-1 22:10:39 | 显示全部楼层
FishC 发表于 2026-9-1 22:00
关于 scanf 格式字符串中的普通字符,确实存在一个大坑。

scanf("enter your number : %d", &num);  ...

我还有个问题 我用getchar第一次为了读掉\n 那这个\n是发现没有接受的赋值 被内存或者缓冲区自动释放掉了吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-1 22:10:46 | 显示全部楼层
11063216906 发表于 2026-09-01 22:10
FishC 发表于 2026-9-1 22:00
关于 scanf 格式字符串 ...


\n 不是“自动释放”,而是被你调用 getchar() 时“读取消耗”掉了。缓冲区就像一个排队队列,getchar() 每调用一次,就从头取走一个字符,这个字符从缓冲区中移除,被返回给程序。如果你没有用变量接收它,这个返回值就被直接丢弃了,但缓冲区中确实少了一个字符。这个过程不是操作系统自动清理内存,而是你主动调用函数把它“消费”掉了。如果缓冲区里某个字符一直放着,它就会一直占用空间,直到程序结束或缓冲区被清空。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-9-18 21:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表