鱼C论坛

 找回密码
 立即注册
查看: 3095|回复: 6

[已解决]关于scanf的问题

[复制链接]
发表于 2022-11-25 22:04:34 | 显示全部楼层 |阅读模式
60鱼币
  1. $ cat test0.c
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5.         char name[10];

  6.         scanf("%s", name);
  7.         printf("%s\n", name);

  8.         return 0;
  9. }
  10. $ gcc test0.c -o test0 && ./test0
  11. 百合花
  12. 百合花
复制代码

  1. $ cat test1.c
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5.         char *name;

  6.         scanf("%s", name);
  7.         printf("%s\n", name);

  8.         return 0;
  9. }
  10. $ gcc test1.c -o test1 && ./test1
  11. 百合花
  12. 段错误 (核心已转储)
复制代码

  1. $ cat test2.c
  2. #include <stdio.h>

  3. int main(void)
  4. {
  5.         char *name;

  6.         name = "百合花";
  7.         printf("%s\n", name);

  8.         return 0;
  9. }
  10. $ gcc test2.c -o test2 && ./test2
  11. 百合花
复制代码



第一个scanf对字符数组赋值,成功
第二个scanf对字符指针赋值,失败
第三个直接对字符指针赋值,成功
如上三种情况,我现在很混乱。
不知道scanf怎么用,也不知道字符数组和字符指针怎么赋值,感觉之前学的东西混成一团浆糊了。
这三种情况为什么会这样啊???
最佳答案
2022-11-25 22:04:35
本帖最后由 jackz007 于 2022-11-25 22:24 编辑
  1.         char * name       ;         // name 只是一个指针,并未指向任何内存地址
  2.         scanf("%s", name) ;         // 把键盘输入存入一个无效的内存地址,导致程序奔溃。
复制代码

       一个指针在使用前必须要做 1 件事,一定要指向一个可以使用的存储空间
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main(void)
  4. {
  5.         char * name                 ;
  6.         name = (char *) malloc(256) ;  // 使用前,一定要为 name 分配足够的存储空间
  7.                                        // 这一句的意思是让 name 指向新分配的 256 字节的存储空间
  8.         scanf("%s", name)           ;
  9.         printf("%s\n", name)        ;
  10.         free(name)                  ;  // name 的存储空间使用完毕后,要及时释放
  11.         return 0;
  12. }
复制代码

最佳答案

查看完整内容

一个指针在使用前必须要做 1 件事,一定要指向一个可以使用的存储空间。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-11-25 22:04:35 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-11-25 22:24 编辑
  1.         char * name       ;         // name 只是一个指针,并未指向任何内存地址
  2.         scanf("%s", name) ;         // 把键盘输入存入一个无效的内存地址,导致程序奔溃。
复制代码

       一个指针在使用前必须要做 1 件事,一定要指向一个可以使用的存储空间
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main(void)
  4. {
  5.         char * name                 ;
  6.         name = (char *) malloc(256) ;  // 使用前,一定要为 name 分配足够的存储空间
  7.                                        // 这一句的意思是让 name 指向新分配的 256 字节的存储空间
  8.         scanf("%s", name)           ;
  9.         printf("%s\n", name)        ;
  10.         free(name)                  ;  // name 的存储空间使用完毕后,要及时释放
  11.         return 0;
  12. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-11-25 22:11:37 | 显示全部楼层
你第2个代码的name指向哪里了?
第2个改成这样
  1. sh-5.1$ cat main.c
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. int main(void)
  5. {
  6.         char *name;

  7.         name = malloc(10);

  8.         scanf("%s", name);
  9.         printf("%s\n", name);

  10.         free(name);

  11.         return 0;
  12. }
  13. sh-5.1$ ./main
  14. 百合花
  15. 百合花
  16. sh-5.1$
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-11-25 22:12:53 | 显示全部楼层
第二个是因为指针变量没有初始化吧,如果你  char a[10]    然后      name=a; 其他都不变,就没有问题了
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-11-26 17:19:23 | 显示全部楼层
本帖最后由 桃花飞舞 于 2022-11-26 17:27 编辑

第一个应该可以理解吧。第二个楼上都有解释,第三个是下面这样。

"百合花"  "abcde"  "hello world" 都是字符串,也是一个无名的字符数组

字符串是一个特殊的字符数组
字符指针又可以指向一个字符数组
因此字符指针可以指向一个字符串
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-26 18:53:55 | 显示全部楼层
jackz007 发表于 2022-11-25 22:11
一个指针在使用前必须要做 1 件事,一定要指向一个可以使用的存储空间。

噢噢噢,十分清楚!
我把这些基础又十分重要的点给忘了
我一直把字符指针直接当成一个字符串变量,已经忘记它是指针了
感谢
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-26 18:54:48 | 显示全部楼层
人造人 发表于 2022-11-25 22:11
你第2个代码的name指向哪里了?
第2个改成这样

你们回答的好快啊
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-23 04:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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