【问题标题】:Segmentation fault when reading arguments from command line [closed]从命令行读取参数时出现分段错误[关闭]
【发布时间】:2025-07-30 11:50:01
【问题描述】:

我正在尝试在 c 中实现一个重复的 cat 函数。我遇到了分段错误,我找不到原因。

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




int main(int argc,char *argv[])
{
    char* s;        /* input string */

    int c;

    if(argc==1){


        while (gets(s)){
            puts(s);
        }
    }

    else{

    FILE *file = fopen( "./argv[1]", "r" );
    while((c=fgetc(file))!=EOF){
        fputc(c,stdout);

    }

    fclose(file);   

    }


    return 0;
}

【问题讨论】:

  • 首先,你应该调试你的程序。如果您不知道该怎么做,这是学习的最佳时机。这几乎总是会立即为您提供错误行,从而使您免于长时间搜索。其次,您从未为 s 分配内存。最后,您要打开./argv[1],而不是"./argv[1]"
  • 啊,是的,每天的 I-write-stuff-to-an-address-where-nothing-is-allocated 问题今天提早出现了。过于本地化,投票关闭。
  • @Lundin 是的,恐怕今天的日常生活中还有更多这样的问题...... -.-
  • 我会使用fread 而不是fgets,因为cat 实际上不需要使用换行符,这样我们就可以避免对长行进行特殊处理。

标签: c segmentation-fault


【解决方案1】:

您正在将字符读入s 而不分配内存:

    while (gets(s)){
        puts(s);
    }

首先使用malloc分配一些内存(稍后你必须free):

    char *s = malloc(some_buffer_size);

或将其修复:

    char s[some_buffer_size];

顺便提一下gets,因为没有办法限制输入的字符数,这会导致缓冲区溢出。请改用fgets(buf, sizeof(buf), stdin)

第二个错误已经被别人指出了,你不能这样叫fopen,改用这个,或者用H2CO3的解决方案:

 FILE *file = fopen( argv[1], "r" );

【讨论】:

  • 另外fopen( "./argv[1]", "r" ); 注意第一个参数
  • 哦,是的。谢谢。但是现在我在尝试从文件中读取时遇到了分段错误
  • @Fazlan 因为你的fopen() 返回NULL。是时候阅读 C 书籍并培养一些常识了。
  • 没有理由不使用固定缓冲区char s[some_buffer_size]
【解决方案2】:

gets(s); - 这里的s 没有初始化为指向任何东西。 fopen( "./argv[1]", "r" ); - 这是错误的。必须是 - fopen(argv[1], "r" );

【讨论】:

    【解决方案3】:
    fopen( "./argv[1]", "r" );
    

    嗯,什么?假设,对吧?

    char buf[0x1000];
    snprintf(buf, sizeof(buf), "./%s", argv[1]);
    FILE *f = fopen(buf, "r");
    

    此外,您正在使用未初始化的 s 指针(您没有为其分配任何内存),因此您的程序也会调用未定义的行为。

    【讨论】:

      【解决方案4】:

      malloc() 基本上是分配内存。最后,您还需要 free() 您的变量以释放分配的空间。

      您应该使用gdb() 来找出错误并调试您的程序。

      【讨论】: