递归函数将字符添加到char数组的末尾

时间:2017-11-06 03:11:05

标签: c recursion

我正在尝试编写一个递归函数,给定一个目录,它将通过该目录递归并打印出内容(想想" tree" linux命令)。

无论如何,这是我的代码:

result=df1.merge(df2,on=['CUSTOMER_KEY'])

下面是一个示例运行,调试打印到函数的下一次调用之间的通知,即path的值传入的值。

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

#define DIRECTORY 4

void recurseDirectory(const char* path, int level);
int isDirectory(const char *filename);
void printLevel(int level);

int main(int argc, char*argv[]){
    char *directory;
    DIR *pdir = NULL;
    struct dirent *pent = NULL;
    FILE curFile;

    if (argc != 2){
        printf("Missing argument: directory. Exitting.\n");
        exit(1);
    }
directory = argv[1];
recurseDirectory(directory, 0);
}


void recurseDirectory(const char *path, int level){
  struct dirent *pent = NULL;
  char *full_path;
  DIR *pdir = opendir(path);

  if (pdir){
    while (pent = readdir(pdir)){
      if(pent != NULL){
    if(pent->d_type == DIRECTORY){

      //add 1 for '/' character
      full_path = calloc(strlen(pent->d_name) + strlen(path) + 1, 0);
      if (full_path){

        strncpy(full_path, path, strlen(path));
        strcat(full_path, "/");
        strcat(full_path, pent->d_name);

        printLevel(level);

        printf("%s\n", path);

        printf("\nDEBUG: path: %s, new_dir: %s\n", path, pent->d_name);
        printf("DEBUG: full_path: %s\n\n", full_path);

        recurseDirectory(full_path, level + 1);
        free(full_path);
      }else{
        printf("Failed to recurse on %s\n", pent->d_name);
      } 
    }else{
      if(pent->d_type != 0){
        printLevel(level);
        printf("%s\n", pent->d_name);
      }
    }
      }
    }
  }
}

void printLevel(int level){
  while (level != 0){
    printf("%s", "    ");
    level--;
  }
}

我一直在抨击这个,因为它对我来说完全没有意义。特别是因为它在调用和输入函数之间打印出两个完全不同的值。

感谢任何人都能给我的帮助。

1 个答案:

答案 0 :(得分:2)

我一开始并没有注意到这一点,

full_path = calloc(strlen(pent->d_name) + strlen(path) + 1, 0);

但这是错误的,因为calloc()个参数都不是0有意义的。相反,尝试

name_length = strlen(pent->d_name);
path_length = strlen(path);
full_path = malloc(name_length + path_length + 1);

使用strncpy()时需要注意。虽然在某种意义上它不会写出超过n个字符的安全性,但它很危险,因为如果'\0'内没有n,它就会跳过它首先是strcpy(full_path, path); 个字符,所以

calloc()

应该解决你的问题。

更多,

  1. 不要0,除非您确实要将所有字节初始化为'\0'。主要是因为,您可以隐藏逻辑中的错误,因为无论您是否执行正确的计算,字符串都会strcat()终止。

  2. 不要那样使用snprintf(),使用更适合您想要的strlen()

  3. 不要在同一个未修改的字符串上多次调用strcat()
  4. 关于我不使用 strcat()的评论:null如果您只使用一次就可以了,因为没有更好的方法来连接两个字符串,但使用它多次效率低下。

    由于c中的字符串是char终止的memcpy()数组,您可以通过存储它们的长度并使用name_length = strlen(pent->d_name); path_length = strlen(path); full_path = malloc(name_length + path_length + 2); if (full_path != NULL) { memcpy(full_path, path, path_length); full_path[path_length] = '/'; memcpy(full_path + path_length + 1, pent->d_name, name_length); full_path[path_length + name_length + 1] = '\0'; } 直接连接字符串,在这种情况下,您需要将长度存储到计算最终大小并分配适当的内存量,回到我的示例,关于如何正确分配内存我们可以做到这一点

    strcat()

    这不是不安全的,因为您计算结果字符串的长度并为其分配足够的空间,然后使用该信息逐步填充它。

    虽然您可以使用strcpy()实现此目的而不存储长度,但您应该始终记住,字符串长度不会存储在ac程序中的任何位置,并且每次使用strcat()时都会{\ n} {{1} }或strlen()程序将扫描字符串以查找终止'\0'