【问题标题】:C: Reading in a file of strings into an array of char *sC: 将字符串文件读入 char *s 数组
【发布时间】:2011-08-01 16:44:03
【问题描述】:

我有这样的事情(没有间距问题),我正在读取一个包含由# 符号分隔的字符串的文件,并尝试将它们中的每一个读入char *s 的数组中。但是,每个包含字符串的char* 都与字符串的确切长度相同。不过这有点麻烦。

char * fragments[1000];
 char temp[20];
      while (i < numFrags) {
          if (fscanf(fp, "#%15[^#]#", temp) == 1) {
            char entry[strlen(temp)];
        entry = strcpy(entry, temp);
        fragments[i++] = entry;
        printf("%d\n", strlen(temp));

          }
      }

想法?

【问题讨论】:

  • "a little buggy" 没用。请告诉我们实际存在哪些错误,例如您输入的内容、预期的内容以及输出的内容。
  • char * 怎么可能是“字符串的确切长度”?还是您的意思是每个 char * 必须指向等长字符串集合中的一个?
  • 我认为“a little buggy”是 OP 的隐喻:你看,每个字符串都包含它携带的字符,就像一辆小车或一辆小红色马车一样。我可能是错的。
  • 我不确定我是否确切地知道你想从你的函数中得到什么,但一个快速解决你问题的方法是使用 malloc 和 free 在堆上使用动态分配,而不是使用固定大小的数组。
  • 一个问题是在本地分配数组entry,然后保留它的地址。我也不知道fscanf的使用是否正确,因为我不知道输入格式。

标签: c arrays char scanf


【解决方案1】:

您的问题是您正在重用entry 数组。

看看我们有fragments[i++] = entry; 的所有i。最后,每个片段都将指向同一个地方,因此将包含相同的字符串(在这种情况下,它将是最后读取的字符串)。

似乎您尝试通过同时使用tempentry 数组来解决此问题,但最后您也可以让fscanf 直接写入entry 数组.


您可能遇到的另一个问题是,如果您的指针指向一个在堆栈上自动分配的数组(即:在函数内声明的数组)。在你的函数返回后,这些内存位置会被你的程序重用,你的指针可以开始指向无效数据(因为这是 C,使用这些损坏的字符串会导致各种崩溃和不良程序行为)。


你的问题基本上是内存分配问题,所以有很多解决办法。

  1. 使fragments 成为字符数组的数组(而不仅仅是指针)。这样,您就可以安全地为每个字符串使用不同的内存。

    char fragments[2000][20]; //can hold 2000 19-character strings
    for(i=0; i<N; i++){
        scanf("%d", fragments[i]);
    }
    

    这种解决方案的优点是简单,并且所有内存都是预先分配的。

  2. malloc 使用动态内存分配。这允许您为每个字符串选择不同大小的数组,还允许您在运行时而不是编译时选择数组的大小。

    char* fragments[2000];
    char entry[MAX_FRAGMENT_LENGTH]; //temporary buffer for strings
    for(i=0; i<N; i++){
        scanf("%d", entry[i]);
        //dynamically allocate an array, just big enough to fit our string in.
        fragments[i] = malloc(sizeof(char) * (1 + strlen(entry));
        strcpy(fragments[i], entry);
    }
    

    这种方法的主要优点是它非常灵活,同时仍然相当简单。主要的缺点是,您需要在使用完 malloc-ed 的所有指针后对它们进行 free 处理(否则会导致内存泄漏)。

  3. 手动进行“动态分配”,使用单个大缓冲区来包含所有字符串。

    char buffer[2000*20];
    char* fragments[2000];
    char* next_empty_location = buffer;
    for(i=0; i<N; i++){
        scanf("%d", next_empty_location);
        fragments[i] = next_empty_location;
        next_empty_location += strlen(next_empty_location) + 1;
    }
    

    如果您不能/不想/不允许使用malloc 解决方案,这是最接近的解决方案。可能更难理解(如果您遇到 C 方面的问题),但它似乎最适合模糊的“每个包含字符串的 char* 很大程度上是字符串的确切长度”限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    相关资源
    最近更新 更多