用C中多个文本文件的单词填充动态二维数组

Fill a dynamic 2D array with words of multiples text files in C

使用此 C 代码,我想用 return 由 readdir 函数编辑的每个不同文本文件中解析的单词填充一个动态的 char 数组。

#include <string.h>                                                             
#include <malloc.h>                                                             
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

                                            
char *getWord(FILE *fp){
    char word[100];
    int ch, i=0;

    while(EOF!=(ch=fgetc(fp)) && !isalpha(ch))
        ;//skip
    if(ch == EOF)
        return NULL;
    do{
        word[i++] = tolower(ch);
    }while(EOF!=(ch=fgetc(fp)) && isalpha(ch));

    word[i]='[=10=]';
    return strdup(word);
}

int readWords(const char * fn,char ** arr){
    char *word;
    FILE * fp;
    int size=0;
    //read first time to get the number of words
    fp=fopen(fn,"r");

    while(word=getWord(fp)){
        size++;
    }

    fclose(fp);
    printf("size:%d\n",size);
    arr = (char **) malloc (size * sizeof (char *));
    //reopen to insert in dynamic array
    fp=fopen(fn,"r");
    for (int i = 0; i < size; i++){
        arr[i] = (char *) malloc (100 * sizeof (char));
        word=getWord(fp);
        // printf("%s",word);
        strcpy(arr[i],word);
    }
    fclose(fp);

    return size;
}

int main(int narg, char *arg[] )
{
    struct dirent *de;  // Pointer for directory entry
    char absdir[256];
    char absfn[256];
    FILE * F;
    int s;

    // opendir() returns a pointer of DIR type. 
    DIR *dr = opendir(arg[1]);
    strcpy(absdir,arg[1]);
    strcat(absdir,"/");

  
    if (dr == NULL)  // opendir returns NULL if couldn't open directory
    {
        printf("Could not open current directory" );
        return 0;
    }
  

    while ((de = readdir(dr)) != NULL){
        if (de->d_type!=4){ // is file?
            strcpy(absfn,absdir);
            strcat(absfn,de->d_name);
            printf("abs_fn:%s \n",absfn);
            char** arr_words;

            s=readWords(absfn,&arr_words);

            printf("%s number of words:%d\n", absfn,s);
            for (int i=0;i<s;i++)
                printf("word %d:%s\n",i,arr_words[i]);
            
            //free 2D array

            for(int i=0;i<s;i++)
                free(arr_words[i]);
            free(arr_words);

        }
            
    }
    closedir(dr);    
    return 0;
}

这些词用 getWord 解析得很好,但我找不到在参数中填充 char **arr passed 并在后面的主函数中使用它的解决方案。 我想用以下形式动态分配 char **arr_words

arr_words[0]=First word of file text
arr_words[1]=Second word
arr_words[s-1]=Last Word

Readword函数return每个文件中读取的字数。

谢谢

您的错误是此处描述的更高级的问题之一:

arr 是局部变量。它是一个 指向指针数组 中第一个指针的指针。为了return this to main(现在坚持),你的函数需要传递一个指向指针的指针到指针数组中的第一个指针...

或者在普通 C 中,可怕的三星级编程,char***。但这实际上是它的一个有效用途,关于存在的三个间接级别的唯一有效用途。

或者,您可以只对 char** 使用 return 并跳过这个额外的间接级别,这可能更具可读性。

使用哪种形式有点主观,但您需要将函数更改为以下之一:

int readWords(const char * fn, char*** arr)
{
  ... 
  *arr = malloc (size * sizeof (char *))
  ...
}

char** readWords(const char * fn, int* wordsRead)
{
   ...
   arr = malloc (size * sizeof (char *));
   ...
   *wordsRead = size;
   return arr;
}
#include <string.h>                                                             
#include <malloc.h>                                                             
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

                                            
char *getWord(FILE *fp){
    char word[100];
    int ch, i=0;

    while(EOF!=(ch=fgetc(fp)) && !isalpha(ch))
        ;//skip
    if(ch == EOF)
        return NULL;
    do{
        word[i++] = tolower(ch);
    }while(EOF!=(ch=fgetc(fp)) && isalpha(ch));

    word[i]='[=10=]';
    return strdup(word);
}

char** readWords(const char * fn,int *wordsRead){
    char *word;
    char**arr;
    FILE * fp;
    int size=0;
    //read first time to get the number of words
    fp=fopen(fn,"r");

    while(word=getWord(fp)){
        size++;
    }

    fclose(fp);
    printf("size:%d\n",size);
    arr = malloc (size * sizeof (char *));
    //reopen to insert in dynamic array
    fp=fopen(fn,"r");
    for (int i = 0; i < size; i++){
        arr[i] = (char *) malloc (100 * sizeof (char));
        word=getWord(fp);
        // printf("%s",word);
        strcpy(arr[i],word);
    }
    fclose(fp);
    *wordsRead = size;

    return arr;
}



int main(int narg, char *arg[] )
{
    struct dirent *de;  // Pointer for directory entry
    char absdir[256];
    char absfn[256];
    FILE * F;
    int s;
    int wordsRead;
    char buffer[100];

    // opendir() returns a pointer of DIR type. 
    DIR *dr = opendir(arg[1]);
    strcpy(absdir,arg[1]);
    strcat(absdir,"/");

  
    if (dr == NULL)  // opendir returns NULL if couldn't open directory
    {
        printf("Could not open current directory" );
        return 0;
    }
  

    while ((de = readdir(dr)) != NULL){
        if (de->d_type!=4){ // is file?
            strcpy(absfn,absdir);
            strcat(absfn,de->d_name);
            printf("abs_fn:%s \n",absfn);
            char **arr_words;
            arr_words=readWords(absfn,&wordsRead);

            printf("%s number of words:%d\n", absfn,wordsRead);
            for (int i=0;i<wordsRead;i++){
                
                printf("word %d:%s\n",i,arr_words[i]);
            }
            //free array of pointers

            for(int i=0;i<s;i++)
                free(arr_words[i]);
            free(arr_words);

        }
            
    }
    closedir(dr);    
    return 0;
}