【问题标题】:Strcpy changing struct int arraystrcpy 改变 struct int 数组
【发布时间】:2017-04-09 02:36:09
【问题描述】:

我有一个 C 结构体,我创建了一个这个结构体的数组

typedef struct {
    int aNum;
    char name[20];
    char sym[10];
    char class[30];
    float weight;
    int shell[SHELLS];
} element_t;
element_t elements[MAX_ELEMENTS];

我要求用户输入 (1 Hydrogen H other_nonmetals 1.008 1 0 0 0 0 0 0),然后我根据空格将其分成一个数组。 我通过调用一个函数来获取每个用户的输入,

for(int i=0;i<N;i++) 
    scan_element(i);

功能:

void scan_element(int i) {
    char *array[12];
    char str[100];
    int j=0;
    if (fgets(str, 100, stdin)) {
        array[j] = strtok(str," ");
        while(array[j]!=NULL)
        {
            array[++j] = strtok(NULL," ");
        }
    }
    elements[i].aNum = (int) strtol(array[0], NULL, 10);
    if(i>0)
        for(int k=5;k<SHELLS+5;k++)
            printf("%d ",elements[i-1].shell[k]);
    printf("\n");
    strcpy(elements[i].name, array[1]);
    strcpy(elements[i].sym, array[2]);
    strcpy(elements[i].class, array[3]);
    elements[i].weight = (strtod(array[4],NULL));
    for(int k=5;k<SHELLS+5;k++)
        elements[i].shell[k] = (int) strtol(array[k], NULL, 10);
}

如果我只输入 1 个元素,shell int 数组很好,但是当我输入另一个元素时,它会弄乱前一个元素的 shell 数组。它应该看起来像1 0 0 0 0 0 0,它适用于当前元素,但是当我输入另一个元素时,shell 数组看起来像1 0 82 1684104524 0 0 0。我想在我调用strcpy 之后会发生这种情况,之前它打印得很好,但是在我第一次调用strcpy 之后,它会向数组中添加随机数。

我该如何解决它,以便我可以输入多个元素而不会弄乱前一个元素的 shell 数组?它只会弄乱 shell 数组,与之前的结构无关。

【问题讨论】:

  • 出于调试目的,强烈建议结构定义包含一个tag 名称,这样调试器,如gdb,可以只给结构实例,它会输出每个字段的内容
  • 建议,保持逻辑简单,将字段内容直接放入结构体的字段中,而不是尝试保存单个字段并稍后分配到结构体实例中。
  • 请使用调试器并单步调试您的代码,这样您就可以看到出了什么问题。
  • @user3629249 关于您的第一条评论:您是对的,但是如果您继续阅读代码,他会从该数组复制到结构之前 它变得重叠或无效,所以这个建议是无关紧要的。第二条评论:这不是一个循环。第四条评论:这不是便携式反序列化的例子。第五条评论:同样,这不是一个循环。最后:请先学习 C,然后再尝试教它。
  • 由于我误读了语句:if( fgets() ),我不得不问当代码退出'if()'代码块时代码在做什么(但对fgets()的调用失败) ?将垃圾设置为 elements[i] 结构。

标签: c arrays struct strcpy


【解决方案1】:

结构元素 int shell[SHELLS];

索引范围从 0 到 (SHELLS-1)。

所以 shell[0] .. shell[SHELLS-1] 是有效的。

以下赋值超出范围:

for(int k=5;k<SHELLS+5;k++)
    elements[i].shell[k] = (int) strtol(array[k], NULL, 10);

shell[SHELLS]、shell[SHELLS+1]、shell[SHELLS+2]、shell[SHELLS+3] 和 shell[SHELLS+4] 将越界,导致未定义的行为。 你看到的那些数字恰好是那些超出内存空间的数字。

我认为你想做这样的事情:

  int iShellCnt = 0;

  for(int k=5;k<SHELLS+5;k++)
      elements[i].shell[iShellCnt++] = (int) strtol(array[k], NULL, 10);

【讨论】:

  • 实际上,我会将+ 5 移动到循环中,如下所示:for (size_t k = 0; k &lt; SHELLS &amp;&amp; array[k]; k++) { element[i].shell[k] = strtol(array[k + 5], NULL, 10); }...但这没关系,请从我这里获得 +1。
【解决方案2】:

顺便说一句:SHELLS 的定义是什么?

以下是问题的根源:

以:

开头的代码块
for(int k=5;k<SHELLS+5;k++) 

将第一个条目放入

elements[i].shell[5] 

并继续放置数据直到很长一段时间后 shell[] 数组的末尾,此结果是未定义的行为,并且可能/将导致段错误事件。

【讨论】:

    猜你喜欢
    • 2014-02-04
    • 2021-08-28
    • 2014-10-20
    • 2016-12-21
    • 1970-01-01
    • 2016-06-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多