我正在尝试编写一个函数,该函数接收指向文件的指针和两个字符串(文件名和模式)。它应该询问文件名,并在进行错误检查时打开文件。但是代码无法编译,我花了几个小时寻找原因。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 41
char* s_gets(char *str, int len);
void openFilename(FILE* fp, char* fname, char* mode);
int main(void)
{
char fname[LEN];
FILE *fp = NULL;
int ch;
// This works
printf("Enter a filename: ");
s_gets(fname, LEN);
fp = fopen(fname, "r");
// This does not
// openFilename(fp, fname, "r");
while ((ch = getc(fp)) != EOF)
putchar(ch);
fclose(fp);
return 0;
}
char* s_gets(char *str, int len)
{
char* ret_val;
char* newline;
ret_val = fgets(str, len, stdin);
if (ret_val) {
newline = strchr(str, '\n');
if (newline)
*newline = '\0';
else
while (getchar() != '\n') continue;
}
return ret_val;
}
void openFilename(FILE *fp, char *fn, char *mode)
{
printf("Enter a filename: ");
s_gets(fn, LEN);
printf("Opening %s... ", fn); // This never runs!
if ((fp = fopen(fn, mode)) == NULL) {
fprintf(stderr, "Couldn't open %s. Quitting.\n", fn);
exit(EXIT_FAILURE);
}
}
如果我从main调用s_gets()
函数就可以正常工作,但是一旦从openFilename()
调用它,我就会得到一个Segmentation fault: 11
,它通常与数组无关, 对?因此,我假设我没有正确地将文件名的字符串参数传递给openFilename()
,但是我该怎么做呢?
答案 0 :(得分:0)
将变量传递给函数时,按值传递而不是引用。因此,当在函数中更改变量的值时,将更改传递到堆栈的副本,但不会更改调用者的变量实际值。当您通过引用传递而不是将副本传递到堆栈上时,其地址将传递到堆栈上并更改该地址上的值。
指针同样如此,当您传递指针时,尽管指针指向的值仍然相同,但指针的副本仍传递到堆栈上;但是,如果要更改指针本身,则需要将指针的地址传递给函数。
将openFilename(FILE* fp, char* fname, char* mode)
更改为openFilename(FILE** fp, char* fname, char* mode)
并使用openFilename(&fp, fname,"r");
调用函数