鱼C论坛

 找回密码
 立即注册
查看: 1424|回复: 2

[已解决]关于结构体内char数组内容更换问题

[复制链接]
发表于 2022-11-29 17:03:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 壳970527 于 2022-11-29 17:06 编辑
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define SaidaiNagasa 14
  4. struct machi {
  5.     int menseki, jinkou;
  6.     char namae[SaidaiNagasa + 1];
  7. };
  8. struct machi newMachi(struct machi s, struct machi t) {
  9.     struct machi rt;
  10.     int j = 0;
  11.     rt.jinkou = s.jinkou + t.jinkou;
  12.     rt.menseki = s.menseki + t.menseki;
  13.     for (int i = 0; s.namae[i] != '\0' ; i++)
  14.     {
  15.         rt.namae[j] = s.namae[i];
  16.         j++;
  17.     }
  18.     for (int i = 0; t.namae[i] != '\0' ; i++)
  19.     {
  20.         rt.namae[j] = t.namae[i];
  21.         j++;
  22.     }
  23.     if (SaidaiNagasa < strlen(rt.namae))
  24.     {
  25.         rt.namae = "**too long**";
  26.     }
  27.    
  28.     return rt;
  29. }

  30. double MitsudoKeisan(struct machi t) {
  31.     double v;
  32.     v = (double) t.jinkou/t.menseki;
  33.     return v;
  34. }

  35. void printMachi(struct machi t) {
  36.     printf("menseki=%d jinkou=%d mitsudo=%.2f name=%s \n",t.jinkou,t.menseki,MitsudoKeisan(t),t.namae);
  37. }

  38. #define MachiKazu (sizeof(list)/sizeof(struct machi))  
  39. int main(void) {
  40.     struct machi rt;
  41.     int t1, t2, i;
  42.     struct machi list[] = {      
  43.         {34, 22, "Honmachi"}, {31, 17, "Kishine"}, {41, 18, "Kosugi"},
  44.         {14, 11, "Kouen"}, {28, 35, "Fujisawa"}, {52, 12, "Kouza"},
  45.         {17, 89, "Musashi"}, {37, 13, "Oono"}, {40, 53, "Ootsuka"},
  46.         {15, 85, "Sagami"}, {21, 67, "Shibuya"}, {34, 15, "Uehara"},
  47.         {19, 60, "Yoyogi"}, {38, 11, "Dai"}
  48.     };
  49.     printf("list of cities\n");
  50.     for (i = 0; i < MachiKazu; i++) {
  51.         printf("%-2d ", i);
  52.         printMachi(list[i]);
  53.     }
  54.     while (1) {
  55.         printf("Machi(int int): ");
  56.         fflush(stdout);
  57.         scanf("%d", &t1);
  58.         scanf("%d", &t2);
  59.         if (t1 < 0 || t2 < 0 || t1 >= MachiKazu || t2 >= MachiKazu || t1 == t2)
  60.                 break;
  61.         rt = newMachi(list[t1], list[t2]);
  62.         printf("nagasa=%d ", strlen(rt.namae));
  63.         printMachi(rt);
  64.     }
  65.     return 0;
  66. }

复制代码


这个结构体是人口面积以及城市名的结构体。MitsudoKeisan(struct machi t) 这个函数时关于人口密度的计算。
这道题的问题是2个结构体相结合后,他的人口和面积是直接相加,城市名字是直接连接到后面,但是如果城市名字的长度超过SaidaiNagasa 14 这个数值之后我希望他显示**too long**,也就是在我打红字的地方,
    第25行代码   rt.namae = "**too long**";
也就是更换成**too long**的位置报错我不知道错在哪个地方,也不知道应该如何更改,希望大佬能够帮忙解惑一下。谢谢!
最佳答案
2022-11-29 17:15:14
本帖最后由 jackz007 于 2022-11-29 21:40 编辑

          字符串不可以用等号直接赋值(定义时赋值属于例外),应该通过函数。
  1.         strcpy(rt . name , "**too long**") ;
复制代码

          这个函数存在一个原则问题
  1. struct machi newMachi(struct machi s, struct machi t) {
  2.     struct machi rt;
  3. . . . . . .
  4.     return rt;
  5. }
复制代码

         返回值 rt 是函数的一个局部变量,这是绝对不允许的,因为,局部变量 rt 的生命周期只是在函数被调用期间,函数一旦退出,函数中所有局部变量所占用的内存会被同时回收,也就是说,等不到被调用端接收、使用,局部变量 rt 就已经被销毁掉了。
         正确的做法是在调用端定义结构体 rt,调用函数的时候,把 rt 的地址作为输入参数传递到函数,函数负责为 rt 填入数据,调用结束后,不用 return,在调用端 rt 就已经被改好了。
  1. void machi newMachi(struct machi * rt , struct machi s, struct machi t) {
  2. . . . . . .
  3.         strcpy(rt -> name , "**too long**") ;
  4. }
复制代码

         函数中所有对 rt 成员的访问要把 . 统统改成 ->,例如,把 rt . name 改成 rt -> name。其它函数如果存在相同情况(返回结构体)的必须全改!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-29 17:15:14 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-11-29 21:40 编辑

          字符串不可以用等号直接赋值(定义时赋值属于例外),应该通过函数。
  1.         strcpy(rt . name , "**too long**") ;
复制代码

          这个函数存在一个原则问题
  1. struct machi newMachi(struct machi s, struct machi t) {
  2.     struct machi rt;
  3. . . . . . .
  4.     return rt;
  5. }
复制代码

         返回值 rt 是函数的一个局部变量,这是绝对不允许的,因为,局部变量 rt 的生命周期只是在函数被调用期间,函数一旦退出,函数中所有局部变量所占用的内存会被同时回收,也就是说,等不到被调用端接收、使用,局部变量 rt 就已经被销毁掉了。
         正确的做法是在调用端定义结构体 rt,调用函数的时候,把 rt 的地址作为输入参数传递到函数,函数负责为 rt 填入数据,调用结束后,不用 return,在调用端 rt 就已经被改好了。
  1. void machi newMachi(struct machi * rt , struct machi s, struct machi t) {
  2. . . . . . .
  3.         strcpy(rt -> name , "**too long**") ;
  4. }
复制代码

         函数中所有对 rt 成员的访问要把 . 统统改成 ->,例如,把 rt . name 改成 rt -> name。其它函数如果存在相同情况(返回结构体)的必须全改!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-30 16:40:45 | 显示全部楼层
jackz007 发表于 2022-11-29 17:15
字符串不可以用等号直接赋值(定义时赋值属于例外),应该通过函数。

          这个函数存在 ...

不好意思回复太慢了,感谢大佬,修改了之后没问题了!谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-7 03:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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