0

我可以使用一些帮助来理解令我困惑的事情。它涉及到 fopen() 读取文件的位置。

以下代码(使用 gcc 4.5.2 编译的 C):

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

void try_fopen(FILE* f_handle, const char* f_name, const char* mode) {
    f_handle = fopen(f_name, mode);
    if( f_handle == NULL ) {
        fprintf(stderr, "Error: Unable to open '%s'.", f_name);
        exit(EXIT_FAILURE);
    }
}

int cnt_ones(FILE* pFile) {
    int c;
    int n = 0;

    do {
      c = fgetc (pFile);
      if (c == '1') n++;
    } while (c != EOF);

    return n;
}

为什么将 fopen 放在函数中会产生 Segfault:

int main (int argc, char** argv) {
    FILE * pFile;
    try_fopen(pFile, argv[1], "r"); // Gives a Segfault

    printf ("The file contains %d ones.\n", cnt_ones(pFile) );
    fclose (pFile);

    return 0;
}

将其放入 main 时(连同 if 没有):

int main (int argc, char** argv) {
    FILE * pFile;
    pFile = fopen(argv[1], "r"); // While this doesn't give a Segfault
    if( pFile == NULL ) {
        fprintf(stderr, "Error: Unable to open '%s'.", argv[1]);
        exit(EXIT_FAILURE);
    }

    printf ("The file contains %d sign characters.\n", cnt_ones(pFile) );
    fclose (pFile);

    return 0;
}
4

4 回答 4

4

C 是按值传递,而不是按引用传递,因此您需要将指针传递给pFile,否则不要在函数范围之外更改它:

void try_fopen(FILE** f_handle, const char* f_name, const char* mode) {
    *f_handle = fopen(f_name, mode);
    if( *f_handle == NULL ) {
        fprintf(stderr, "Error: Unable to open '%s'.", f_name);
        exit(EXIT_FAILURE);
    }
}

// ...
try_fopen(&pFile, argv[1], "r");
于 2012-05-14T08:50:42.087 回答
1

因为指针pFile是按值传递给函数的try_open。函数内部修改的值在main. 为了解决这个问题,您需要将指针的地址传递给函数,这样try_open才能接受FILE**并分配fopento的结果*pFile。调用此函数时,您应该传递pFileusing的地址&pFile

于 2012-05-14T08:50:57.607 回答
1

你可以这样做:

File * fp;
try_fopen( &fp,.....); /* void try_fopen (FILE ** fp,....) */

或以下内容:

File * fp = try_fopen("file name"); /* FILE * try_fopen (const char * file_name,...) */
于 2012-05-14T09:02:09.670 回答
0

原因很简单,当你将 FILE* 传递给函数时,它的更新将丢失,因为它是由 Value 传递的。尝试将 FILE ** 传递给函数,它将起作用。有关代码片段,请参阅上面 Binyamin Sharet 的答案

原因可以通过阅读这个链接来理解

或者

您可以更改函数 try_open 以返回 FILE * 作为返回值。

FILE *try_fopen(const char* f_name, const char* mode) 
{ 
   FILE *f_handle = NULL;    
  *f_handle = fopen(f_name, mode);     
   if( *f_handle == NULL ) 
   {         
     fprintf(stderr, "Error: Unable to open '%s'.", f_name);         
     exit(0);     
   } 
} 

  //In the main function.
  FILE *pFile = try_fopen(argv[1], "r");
于 2012-05-14T08:51:42.277 回答