用C语言读取一个文件,并将内容传递给main()



我是c的新手,我在访问从文件读取的数据时遇到了问题。我试图做的事情背后的想法是获取一个文本文件,读入它,创建一个数组,并设置该数组的内容等于文件的内容(字符)。

现在,这就是我困惑的地方。要在main方法中操作tStr,我需要能够访问它在read方法中的内容集。如果我试图访问主类中的tStr数组,根据我的理解,你不能考虑你只设置了它的大小,但没有传递任何值。

如果我想编辑应该包含文本文件内容的数组tStr,我如何从readFile()main()获取数据

#include <stdio.h>
    #include <stdlib.h>
    #define size 1000
    int readFile(char fn[], char tStr[]);
    int main(int argc, char* argv[]){
        char tStr[size];
        return 0;
    }
    int readFile(char fn[], char tStr[])
    {
        FILE *fptr;
        char c;
        int i = 0;
        if ((fptr=fopen(fn, "r")) == NULL){
            printf("Error: unknown file %sn", fn);
            exit(1);
        }
        while ((c = fgetc(fptr)) != EOF)
            tStr[i++] = c;
        tStr[i] = '';
        return i;   
    }

只需调用readFile并将文件路径和要填充文件内容的数组传递给它。

#include <stdio.h>
    #include <stdlib.h>
    #define size 1000
    int readFile(char fn[], char tStr[]);
    int main(int argc, char* argv[]){
        char tStr[size];
        readFile("file.txt",tStr);
        printf("%s", tStr);
        return 0;
    }
    int readFile(char fn[], char tStr[])
    {
        FILE *fptr;
        char c;
        int i = 0;
        if ((fptr=fopen(fn, "r")) == NULL){
            printf("Error: unknown file %sn", fn);
            exit(1);
        }
        while ((c = fgetc(fptr)) != EOF)
            tStr[i++] = c;
        tStr[i] = '';
        return i;   
    }

注意数组必须足够大以容纳文件内容,否则会有未定义的行为。

在传递数组时,正常的c语言习惯是同时传递一个int或size_t形参,指示缓冲区的大小,并且只向缓冲区写入一定数量的字符。

传递一个已经打开的FILE*可能比传递文件路径更好。减轻了文件相关错误指示功能的负担。

有时,有很好的理由能够简单地调用一个函数来读取文件,并让该函数返回一个指针,该指针指向保存文件内容的已分配字符串数组。当您不知道文件有多长时尤其如此。虽然你可以传递一个指针,但它需要一个***参数来处理realloc在重新分配时改变指针地址。

将函数声明为char **并让它返回一个指向已分配数组的指针是处理这种情况的标准方法。此外,选择一些合理数量的指针进行初始分配,并遵循标准的重新分配方案(在realloc上,将当前指针的数量分配给2X),避免了对realloc的昂贵调用和相对昂贵的调用,就像对文件中的每一行调用realloc时那样。

当你动态分配内存时,由你来跟踪内存,保留一个指向内存块开始的指针(这样你可以free它),并在不再需要它时free内存。

下面用一个简短的例子把所有这些谜题拼凑在一起。该示例使用getline从文件中读取行,并使用strdup(分配内存并进行复制)将getline读取的行复制到字符串数组中。如果您有问题,请告诉我:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NMAX 256
char **readtxtfile (char *fn, size_t *idx);
void prn_chararray (char **ca);
void free_chararray (char **ca);
int main (int argc, char **argv) {
    size_t file_size = 0;   /* placeholders to be filled by readtxtfile */
    char *fn = argc > 1 ? argv[1] : NULL;
    /* read each file into an array of strings,
    number of lines read, returned in file_size */
    char **file = readtxtfile (fn, &file_size);
    /* output number of lines read and from where  */
    printf ("n read '%zu' lines from file: %snn", file_size, fn ? fn : "stdin");
    /* simple print function */
    if (file) prn_chararray (file);
    /* simple free memory function */
    if (file) free_chararray (file);
    return 0;
}
char **readtxtfile (char *fn, size_t *idx)
{
    char *ln = NULL;                /* NULL forces getline to allocate  */
    size_t n = 0;                   /* size of ln, 0 - getline decides  */
    ssize_t nchr = 0;               /* number of chars actually read    */
    size_t nmax = NMAX;             /* check for reallocation           */
    char **array = NULL;            /* array to hold lines read         */
    FILE *fp = NULL;                /* file pointer to open file fn     */
    /* open / validate file or read stdin */
    if (fn) {
        if (!(fp = fopen (fn, "r"))) {
            fprintf (stderr, "%s() error: file open failed '%s'.", __func__, fn);
            return NULL;
        }
    }
    else
        fp = stdin;
    /* allocate NMAX pointers to char* */
    if (!(array = calloc (NMAX, sizeof *array))) {
        fprintf (stderr, "%s() error: memory allocation failed.", __func__);
        return NULL;
    }
    /* read each line from stdin - dynamicallly allocated   */
    while ((nchr = getline (&ln, &n, fp)) != -1)
    {
        /* strip newline or carriage rtn    */
        while (nchr > 0 && (ln[nchr-1] == 'n' || ln[nchr-1] == 'r'))
            ln[--nchr] = 0;
    array[*idx] = strdup (ln);  /* allocate/copy ln to array        */
        (*idx)++;                   /* increment value at index         */
        if (*idx == nmax) {         /* if lines exceed nmax, reallocate */
            char **tmp = realloc (array, nmax * 2);
            if (!tmp) {
                fprintf (stderr, "%s() error: reallocation failed.n", __func__);
                exit (EXIT_FAILURE); /* or return NULL; */
            }
            array = tmp;
            nmax *= 2;
        }
    }
    if (ln) free (ln);              /* free memory allocated by getline */
    if (fp != stdin) fclose (fp);   /* close open file descriptor       */
    return array;
}
/* print an array of character pointers. */
void prn_chararray (char **ca)
{
    register size_t n = 0;
    while (ca[n])
    {
        printf (" arr[%3zu]  %sn", n, ca[n]);
        n++;
    }
}
/* free array of char* */
void free_chararray (char **ca)
{
    if (!ca) return;
    register size_t n = 0;
    while (ca[n])
        free (ca[n++]);
    free (ca);
}

$ /bin/getline_readfile_function <~/tmp/fc-list-fonts-sorted-no-path.txt
 read '187' lines from file: stdin
 arr[  0]  andalemo.ttf: Andale Mono - Regular
 arr[  1]  arialbd.ttf: Arial - Bold
 arr[  2]  arialbi.ttf: Arial - Bold Italic
 arr[  3]  ariali.ttf: Arial - Italic
 arr[  4]  arialnbi.ttf: Arial
 arr[  5]  arialnb.ttf: Arial
 arr[  6]  arialni.ttf: Arial
 arr[  7]  arialn.ttf: Arial
 arr[  8]  arial.ttf: Arial - Regular
 arr[  9]  ARIALUNI.TTF: Arial Unicode MS - Regular
 arr[ 10]  ariblk.ttf: Arial
 arr[ 11]  Bailey Script Regular.ttf: Bailey Script - Regular
 arr[ 12]  Bailey_Script_Regular.ttf: Bailey Script - Regular
 arr[ 13]  Belwe Gotisch.ttf: Belwe Gotisch - Regular
 arr[ 14]  Belwe_Gotisch.ttf: Belwe Gotisch - Regular
<snip>

内存检查

$ valgrind ./bin/getline_readfile_function <~/tmp/fc-list-fonts-sorted-no-path.txt
==20259== Memcheck, a memory error detector
==20259== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==20259== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==20259== Command: ./bin/getline_readfile_function
==20259==
 read '187' lines from file: stdin
 arr[  0]  andalemo.ttf: Andale Mono - Regular
 arr[  1]  arialbd.ttf: Arial - Bold
 arr[  2]  arialbi.ttf: Arial - Bold Italic
 arr[  3]  ariali.ttf: Arial - Italic
<snip>
==20259==
==20259== HEAP SUMMARY:
==20259==     in use at exit: 0 bytes in 0 blocks
==20259==   total heap usage: 189 allocs, 189 frees, 9,831 bytes allocated
==20259==
==20259== All heap blocks were freed -- no leaks are possible
==20259==
==20259== For counts of detected and suppressed errors, rerun with: -v
==20259== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

注:如果传递给readtxtfile的指针fnNULL,则从stdin读取input。(这只是增加了输入例程的灵活性)上面的调用也可以很容易地是:

./bin/getline_readfile_function ~/tmp/fc-list-fonts-sorted-no-path.txt

相关内容

  • 没有找到相关文章

最新更新