【问题标题】:Function to change array data - data not changing. C更改数组数据的功能 - 数据不变。 C
【发布时间】:2013-04-24 16:08:12
【问题描述】:

我是 C 新手,但几周前我已经用 pascal 编程了。在 pascal 中,如果您想更改数组数据,您可以通过引用传递,本质上是键入 var myArray。我不知道如何在 C 中做到这一点。我读过很多问题,但似乎都没有。这是我目前所拥有的。

void set_up_elements(char (*array_to_populate)[20])
{
    char* buffer;
    FILE *f;
    f=fopen("elementList.txt","r");
    char copied_text[118][20];
    int i=0;
    while (!feof(f))
    {
        fgets(copied_text[i],80,f);
        ++i;
    }
    //Close the file to free up memory and prevent leaks
    fclose(f);
    f = NULL;
}

这是我填充数组的代码,我将元素周期表中的元素列表读入数组copied_text。这部分有效,它成功填充了函数内部的数组。

int main()
{
    char element_array[118][20];
    set_up_elements(element_array);
<..>
}

这就是我试图调用它的方式。数组element_array 的内容不会改变。有谁知道如何解决这一问题?谢谢。

【问题讨论】:

  • set_up_elements(&element_array);
  • 另外我认为copyed_text应该是[118][80],因为你想复制80个字符,而不是20个字符。
  • c-faq.com/aryptr/pass2dary.html 将二维数组传递给函数
  • 如果文件包含超过 118 行且一行包含超过 20 个字符,则可能会导致崩溃。你会检查那个。无论如何,在set_up_elements 函数的while 循环中将copied_text 替换为array_to_populate(也不需要定义新数组)。

标签: c arrays pointers reference populate


【解决方案1】:

1) 下面一行是错误的

fgets(copied_text[i],80,f);

字符串数组中一个元素字符串的大小是20。并且您在fgets() 函数中读取的最大字符是80

所以改成:

fgets(copied_text[i],sizeof(copied_text[0]),f);

2) 并且您可以更改此代码:

while (!feof(f))
    {
        fgets(copied_text[i],80,f);
        ++i;
    }

while (i<118 && fgets(copied_text[i++],80,f));

3) 你的函数的输入参数

void set_up_elements(char (*array_to_populate)[20])

未在您的函数中使用。似乎您想将其填充到您的函数中,但事实并非如此,您正在使用调用者无法看到的另一个数组(本地数组)

【讨论】:

  • 谢谢,我原来的帖子有一些错误,将 fgets 第一个参数从 copied_text 更改为 array_to_populate 修复了它。谢谢。
【解决方案2】:

应用左右阅读规则来理解问题...

char element_array[118][20] 表示 element_array 是一个由 20 个字符组成的 118 个块组成的数组。

另一方面,char (*array_to_populate)[20] array_to_populate 是一个指向 20 个字符数组的指针,因为有括号。

您可以使用 char (&amp;array_to_populate)[118][20],这意味着 array_to_populate 是对 118 个 20 个字符的块的引用。

也就是说,最大的问题是在您的函数中,您正在读取一个临时数组,而您从未将其复制到传入的数组中。此外,您读取的文件大小错误。以下应该可以完成工作......

#define DIM1 118
#define DIM2 20

void set_up_elements(char (&array_to_populate)[DIM1][DIM2])
{
    int i=0;
    FILE *f=fopen("elementList.txt","r");

    for (i = 0; f && !feof(f) && i < DIM1; i++ )
    {
        fgets(array_to_populate[i],sizeof(array_to_populate[0]),f);
    }

    //Close the file to free up memory and prevent leaks
    fclose(f);
}

【讨论】:

  • 啊,这部分 fgets(array_to_populate 我完全忽略了...我不敢相信,我查看了我的代码 50 次,并没有意识到我没有引用参数的事实...我对此感到很愚蠢...更改后,我用(char (*array_to_populate)[20])(char (&amp;array_to_populate)[DIM1][DIM2])对其进行了测试,它们都可以工作,但是,将其更改为您的方法确实看起来更整洁。我知道 * 是指针的符号,但 & 到底是什么?它本质上是否用作“通过引用传递”符号(如 pascals var arrayToPopulate?
  • 正确... '&' 表示通过引用传递,您将其视为原始变量而不是指向它的指针。它还允许您在原型上定义数组的所有维度,这样您就不能将错误大小的数组传递给它。
  • @Anteara void set_up_elements(char (&amp;array_to_populate)[DIM1][DIM2]) 不会在 C 中编译,那是 C++。您对set_up_elements 的声明和调用是 100% 正确的。您只是没有复制到函数体中的参数中。 (当然,你没有检查你是否留在数组边界内。)
【解决方案3】:
void set_up_elements(char (*array_to_populate)[20])
{
    char* buffer;//unuse var
    FILE *f;
    f=fopen("elementList.txt","r");
    int i=0;
    while (!feof(f))//caution
    {
        fgets(&(*array_to_populate[i]),20,f);
        ++i;
    }
    //Close the file to free up memory and prevent leaks
    fclose(f);
    f = NULL;
}

【讨论】:

  • 取消了反对票并将我的 cmets 删除为不适用。
  • 我的原始帖子是错误的代码,现在是凌晨 2:30,我忽略了一个重要部分,即我将错误的变量传递给 fgets,因此为什么数据在函数之外没有改变.但是,我确实删除了未使用的缓冲区变量,并在阅读您的 //caution 评论时...是因为在您阅读最后一行时不会设置 EOF,即使您在最后行,导致最后一行可能被读取两次?
  • @Anteara 没错。如果你刚刚读完,数据本身会在额外的循环中翻转,但它不会成为 EOF。
  • 请注意,在我提出的解决方案中,我为超过 DIM1 的行添加了一个测试——这可以防止尝试读取额外块的情况发生。
  • 原来如此。应提供此类信息。尽管如果它们比您计划的数据少,我也是一样。
猜你喜欢
  • 1970-01-01
  • 2016-02-02
  • 2017-10-09
  • 1970-01-01
  • 2021-11-25
  • 2023-03-09
  • 2022-08-18
  • 1970-01-01
  • 2015-10-28
相关资源
最近更新 更多