壳970527 发表于 2022-11-29 17:03:57

关于结构体内char数组内容更换问题

本帖最后由 壳970527 于 2022-11-29 17:06 编辑

#include <stdio.h>
#include <string.h>
#define SaidaiNagasa 14
struct machi {
    int menseki, jinkou;
    char namae;
};
struct machi newMachi(struct machi s, struct machi t) {
    struct machi rt;
    int j = 0;
    rt.jinkou = s.jinkou + t.jinkou;
    rt.menseki = s.menseki + t.menseki;
    for (int i = 0; s.namae != '\0' ; i++)
    {
      rt.namae = s.namae;
      j++;
    }
    for (int i = 0; t.namae != '\0' ; i++)
    {
      rt.namae = t.namae;
      j++;
    }
    if (SaidaiNagasa < strlen(rt.namae))
    {
      rt.namae = "**too long**";
    }
   
    return rt;
}

double MitsudoKeisan(struct machi t) {
    double v;
    v = (double) t.jinkou/t.menseki;
    return v;
}

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

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



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

jackz007 发表于 2022-11-29 17:15:14

本帖最后由 jackz007 于 2022-11-29 21:40 编辑

          字符串不可以用等号直接赋值(定义时赋值属于例外),应该通过函数。
      strcpy(rt . name , "**too long**") ;
          这个函数存在一个原则问题
struct machi newMachi(struct machi s, struct machi t) {
    struct machi rt;
. . . . . .
    return rt;
}
         返回值 rt 是函数的一个局部变量,这是绝对不允许的,因为,局部变量 rt 的生命周期只是在函数被调用期间,函数一旦退出,函数中所有局部变量所占用的内存会被同时回收,也就是说,等不到被调用端接收、使用,局部变量 rt 就已经被销毁掉了。
         正确的做法是在调用端定义结构体 rt,调用函数的时候,把 rt 的地址作为输入参数传递到函数,函数负责为 rt 填入数据,调用结束后,不用 return,在调用端 rt 就已经被改好了。
void machi newMachi(struct machi * rt , struct machi s, struct machi t) {
. . . . . .
      strcpy(rt -> name , "**too long**") ;
}
         函数中所有对 rt 成员的访问要把 . 统统改成 ->,例如,把 rt . name 改成 rt -> name。其它函数如果存在相同情况(返回结构体)的必须全改!!!

壳970527 发表于 2022-11-30 16:40:45

jackz007 发表于 2022-11-29 17:15
字符串不可以用等号直接赋值(定义时赋值属于例外),应该通过函数。

          这个函数存在 ...

不好意思回复太慢了,感谢大佬,修改了之后没问题了!谢谢
页: [1]
查看完整版本: 关于结构体内char数组内容更换问题