【问题标题】:Overwriting my array with fgets in C在 C 中用 fgets 覆盖我的数组
【发布时间】:2018-11-19 05:35:08
【问题描述】:

C 中的所有内容都在这里...

我想读取一个 csv 文件,其中 fgets 为每一行分开。我通过浏览我的 csv 文件、读取特定行、将其保存到我的数组中并增加我的连续变量来做到这一点。

我想编写一个程序来将 csv 文件转换为 JSON,并为特定行提供特定标题,但这还有很长的路要走......

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "menu.h"

int main() {
    printf("\n\n\nCode starts...\n");

   int i = 0;
   int j = 0;

   char content[1000];
   char * contentArray[2][9];

   FILE * regel1 = fopen("Regel-1.csv","r");

   while(!feof(regel1)){
        fgets(content, sizeof(content), regel1);
        contentArray[i][j] = content;
        printf("\nThis is contentArray[%i][0]: %s\n", i, contentArray[i][0]);
        i++;
   }

   printf("\nWhile-Loop finished...\n");

   for(int n = 0; n<=1; n++){
       printf("\nThat is contentArray[%i][0]: %s\n", n, contentArray[n][0]);
   }

   fclose(regel1);
     return 0;
}

正如您在我的输出中看到的那样,它首先将 csv 文件的两行不同的行保存到数组中,然后……正如我从测试中知道的那样……用 fgets 覆盖第一个数组条目……

代码开始...

这是 contentArray[0][0]: ME;Wie ist der übliche Abstand der gegnerischen Spieler bei einer mit dem Fuß ausgeführten Spielfortsetzung, z.B. dem Anstoß?;9 米;9,15 米;10 米;2;2;;;

这是 contentArray[1][0]: ME;Welche Art von Freistoß wird an einem beliebigen Punkt innerhalb des Torraums ausgeführt?;Direkte und Indirekte Freistöße für die verteidigende Mannschaft.;Direkte Freistöße für die angreifende Mannschaft.;Indirekte Freistöße für die angreifende Mannschaft.;1;2;;;

While-Loop 完成...

即 contentArray[0][0]: ME;Welche Art von Freistoß wird an einem beliebigen Punkt innerhalb des Torraums ausgeführt?;Direkte und Indirekte Freistöße für die verteidigende Mannschaft.;Direkte Freistöße für die angreifende Mannschaft.;Indirekte Freistöße für die angreifende Mannschaft.;1;2;;;

即 contentArray[1][0]: ME;Welche Art von Freistoß wird an einem beliebigen Punkt innerhalb des Torraums ausgeführt?;Direkte und Indirekte Freistöße für die verteidigende Mannschaft.;Direkte Freistöße für die angreifende Mannschaft.;Indirekte Freistöße für die angreifende Mannschaft.;1;2;;;

非常感谢您的帮助。

提前致谢

GMOSS

【问题讨论】:

  • 试过调试你的代码吗?你做了哪些努力来解决它?

标签: c arrays file csv fgets


【解决方案1】:

@mentallurg 我是用 strcpy 做的,所以我的指针不会随着内容的最新变化而改变:

   int i = 0;
   int csvlength = 0;

   char content[1000];
   char linesArray[maxlength][1000];

   while(!feof(file)){
        fgets(content, sizeof(content), file); //Zeilenweise als String extrahieren
        strcpy(linesArray[i], content); //Kopieren des Strings in das linesArray
        csvlength = max_int(csvlength, i); //Zählen der Anzahl der Zeilen
        i++;
   }

【讨论】:

    【解决方案2】:

    我用 strdup 尝试了你的第二个建议,它有效,我明白为什么:D

    while(!feof(regel1)){
            fgets(content, sizeof(content), regel1);
            char * duplicate = strdup(content);
            contentArray[i][j] = duplicate;
            printf("\nThis is contentArray[%i][0]: %s\n", i, contentArray[i][0]);
            i++;
            free(duplicate);
       }
    

    我也想了解使用三维数组而不是二维数组的版本。如果您能更详细地解释一下,将不胜感激。

    提前致谢!

    GMOSS

    【讨论】:

    • 这里的代码工作。这是因为您将(再次!)有 两个指向同一内存的指针! duplicatecontentArray[i][j] 都将指向同一内存,然后您执行 free(duplicate) 这使得指针contentArray[i][j] 无效。当您全部完成字符串时,您应该调用free
    【解决方案3】:

    实际上你有两个问题。

    第一个在Why is “while ( !feof (file) )” always wrong?询问和回答。

    第二个,也就是你问的问题,是你有一个指针矩阵。您初始化的所有指针全部都将指向相同的位置:数组中的第一个字符content

    要解决您的问题,请将contentArray 设为数组数组数组 并从contents 复制字符串。或者使用常用的strdup函数来复制字符串。

    如果您使用strdup,请不要忘记使用free 来释放strdup 分配的内存。


    您还可以改进其他方面,但不会影响您当前的问题。例如错误处理。如果您无法打开文件并且fopen 返回一个空指针会发生什么?你需要处理这个并且不要继续,因为这会导致undefined behavior

    【讨论】:

    • 你忘了fopen返回值需要检查
    • 感谢您的快速答复。为什么我需要一个数组数组?我有一个二维数组,但我不明白为什么我需要一个三维数组。
    • @GMOSS 因为你没有解释为什么你目前有一个“2d”指针数组,我无法解释为什么你需要一个“3d”数组,除了最后一个“维度”可以是一个数组,因此您可以将字符串复制到其中。
    • 这很重要...我还不需要我的二维数组。我这样做是因为我的下一步是用分号分隔行并获得一个二维数组。所以,实际上我只需要一个一维数组来填充我的 fgets 输出。你的意思是,因为字符串是一个字符数组,我需要我的二维数组来填充我的字符串......?但是如果不使用下一步更改的指针填充它,我该怎么做呢?
    • @GMOSS 如果你有例如char contentArray[2][9][1000] 那么你可以做strcpy(contentArray[i][j], content)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多