【问题标题】:getc and fgetc not working... giving Segmentation faultgetc 和 fgetc 不起作用...给出分段错误
【发布时间】:2020-04-04 00:11:37
【问题描述】:

我正在尝试将一个文件的内容复制到另一个文件中。在我完成之前,我想在屏幕上打印内容以查看一切是否正常。但他们没有。

我包括...

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

我的代码是……

void decodeBin(char * filename){
    //opens  filename for reading and outfilename for writing
    FILE * input = fopen(filename, "r");

    char file_name[] = "";
    strcpy(file_name, filename);
    char out_file[] = "out";
    strcat(out_file, file_name);
    FILE * output = fopen(out_file, "w");


    char ch;
    if (input != NULL){
        while((ch = fgetc(input)) != EOF)
        printf("%c", ch);
    }

    fclose(input);
    fclose(output);
}

我查看了其他堆栈溢出帖子,其中建议检查文件指针是否不为空,我这样做了。怎么了?

【问题讨论】:

  • 使用调试器来帮助你。至少它会立即告诉您 seg 故障发生的位置。它使您可以跟踪程序执行并检查变量。在这种情况下,您的问题是您已将 file_nameout_file 声明为某个固定大小,然后您尝试将更多内容写入缓冲区。在 C 中,数组不会自动增长。您需要分配一些 MAX 大小,或者需要使用动态内存分配。
  • 如果FILE *input = fopen(filename, "r"); 失败,fclose(input); 可能会导致崩溃。您只能安全地关闭一个成功打开的文件。您实际上并没有使用output,但您也没有在关闭它之前检查它是否已成功打开。
  • 关于:FILE * input = fopen(filename, "r"); 后面应该紧跟:if( ! input ) { perror( "fopen for input file failed" ); exit( EXIT_FAILURE ); } 非常相似的语句应该跟在后面:FILE * output = fopen(out_file, "w");
  • 关于:char out_file[] = "out"; 这仅分配 4 个字符。但是,为了避免缓冲区溢出和由此产生的未定义行为,这应该类似于: char out_file[ strlen( "out ) + strlen( file_name ) + 1 ];` 注意:+1 为 NUL 终止符字节留出空间
  • 关于:char file_name[] = ""; 这会生成一个只有 1 个字符的缓冲区,其中包含一个 NUL 字节。因此,将任何内容写入该缓冲区是未定义的行为,并且可能导致段错误事件。建议类似于:char file_name[ strlen( filename ) +1 ]; 后跟:strcpy( file_name, filename );

标签: c file pointers


【解决方案1】:

file_nameout_file 数组的范围之外写入会导致未定义的行为。当您没有为数组指定大小时,大小由您用来初始化它的字符串确定。所以相当于

char file_name[1] = "";
char out_file[4] = "out";

额外的字节用于尾随的空值。

由于您没有为要复制到其中的字符串声明足够大的数组,因此您会得到未定义的行为。

您需要声明数组的大小足以容纳最大可能的文件名。或使用malloc() 根据参数调整大小。

不需要file_name 变量,因为它只是filename 的副本,您可以直接使用它。

char *outfile = malloc(strlen(filename) + sizeof("out"));
sprintf(outfile, "out%s", filename);

然后在函数的最后,做

free(outfile);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多