【问题标题】:String arrays in cc中的字符串数组
【发布时间】:2010-09-06 19:32:18
【问题描述】:

我写了一个读取文件的代码

以下代码有什么问题,如果我打印任何 arrayItem,我总是得到最后一个文件名

#include <stdio.h>
#include <string.h>

char **get_files()
{
    FILE *fp;
    int status;
    char file[1000];
    char **files = NULL;
    int i = 0;
    /* Open the command for reading. */
    fp = popen("ls", "r");
    if (fp == NULL) {
        printf("Failed to run command\n" );
        //exit;
    }

    while (fgets(file, sizeof(file)-1, fp) != NULL) {

        files = (char **)realloc(files, (i + 1) * sizeof(char *));
        //files[i] = (char *)malloc(sizeof(char));
        files[i] = file;
        i++;        
    }
    printf("%s", files[0]);
    return files;
}

int main()
{
char **files = NULL;
int i =0 ;
files = get_files("");

}

【问题讨论】:

  • 关于此代码示例本身:main 未终止,缺少 return 和 }。函数调用不尊重原型。此外,在 C 中,没有参数的函数在括号内使用 void
  • 我喜欢 php、java 和 flex 编程,对于一些 cron 作业处理,我是第一次写这个。无论如何感谢您的建议

标签: c arrays string


【解决方案1】:

你应该使用

files[i] = strdup(file);

而不是

files[i] = file;

第二个版本只让files[i] 指向你的阅读缓冲区,这总是相同的。使用下一个fgets,您将覆盖file 的内容,从而覆盖实际上指向内存中相同位置的file[i] 的内容。 事实上,最后,您所有的file[0]..file[n] 都将指向与file 相同的位置。

使用strdup(..),您正在分配一个新缓冲区并将file 的内容复制到那里。

【讨论】:

    【解决方案2】:

    您的 popen 缺少 pclose。 popen 只是 POSIX,而不是 C89/C99。 示例中没有内存分配检查,这是您的工作;-)

    #include <stdio.h>
    #include <stdlib.h>
    
    char **get_files(char **list)
    {
      FILE *fp;
      char file[1000];
      int i=1;
      /* Open the command for reading. */
      fp = popen("ls -l", "rt");
      if( !fp )
        perror("Failed to run command\n" ),exit(1);
    
      while( fgets(file, sizeof file , fp) ) {
    
        list = realloc(list, ++i * sizeof*list );
        memmove( list+1, list, (i-1)*sizeof*list);
        *list = strcpy( malloc(strlen(file)+1), file);
      }
      pclose( fp );
      return list;
    }
    
    main()
    {
      char **files = get_files(calloc(1,sizeof*files)), **start=files;
      while( *files )
      {
        puts(*files);
        free(*files++);
      }
      free(start);
      return 0;
    }
    

    【讨论】:

    • popen 有任何 c89/c99 标准替代品,该程序的目标是作为 cron 作业运行以处理 linux 机器上的文件,您有什么建议使用? Posix 标准将在所有 linux 机器上运行?
    【解决方案3】:

    在 'ls' 上调用 popen() 是一种不好的方法。看看 opendir()、readdir()、rewinddir() 和 closedir()。

    【讨论】:

    • 这个只是作为例子,我的意图是运行一些linux命令并处理这些输出
    【解决方案4】:

    您正在重用file 数组。读取文件名后,您需要使用strdup 对其进行复制,并将该副本放入files 数组中。否则,files 中的每个元素都指向同一个字符串。

    【讨论】:

      【解决方案5】:

      无论您如何重新分配内存,您在 char 文件 [1000] 中的数组都是一维的(除非我遗漏了一些明显的东西)。如果您正在读取未知数量的文件,那么链表可能是解决此问题的最佳方式。

      【讨论】:

        猜你喜欢
        • 2013-08-16
        • 2011-01-22
        • 2011-08-12
        • 1970-01-01
        • 2012-03-20
        • 2018-04-02
        • 2015-03-27
        • 1970-01-01
        相关资源
        最近更新 更多