1

我正在尝试在Red Hat Linux中模拟cat命令。运行程序时出现分段错误。

例如:

./a.out a > b

a包含你好。我希望 hello 被复制到b.

我的代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char *argv[])
{
    int f, fd, r;
    char buf[100];

    if (argc < 2)
    {
        printf("Error");
        return 0;
    }
    else
    {
        if (!strcmp(argv[2],">"))
        {
            f = open(argv[1],0,00777);

            if (f == -1)
                printf("no file");
            else
            {
                fd = creat(argv[3],00777);
                while( (r = read(f,buf,50)) > 0)
                    write(fd, buf, r);
            }
        }
    }
    return 0;
}

为什么我会收到分段错误?

我有一个类似的程序,我在其中以相同的方式打开和创建文件,并且该程序正在运行,但是这个程序给了我一个分段错误。

4

3 回答 3

6

这可能是因为重定向是由 shell 而不是由您的程序处理的,所以argv[2]存在NULL并且argv[3]不存在。

但是,您应该使用调试器来找出真正发生的事情。然后添加适当的错误检查。

于 2013-04-30T16:22:41.570 回答
4

没有这里你也可以生活gdb——但你必须开始以结构化的方式解决问题:

  • 不要把任何事情视为理所当然。例如,即使您将程序称为program > file,也不要假设它argv看起来像您假设的那样,而是通过输出它们中的每一个来检查它:

    printf("argc: %d\n", argc);
    printf("argv[0]: %s\n", argv[0]);
    printf("argv[1]: %s\n", argv[1]);
    printf("argv[2]: %s\n", argv[2]);
    printf("argv[3]: %s\n", argv[3]);
    // the se can be expressed better with a for loop - but I'll leave that as an exercise for you
    
  • 仅将您已验证的事情视为理所当然:如果您知道argc >= 2,请不要访问argv[2]和/或argv[3]

  • 不要说

    if(argc<2)
    {
        printf("Error");
        return 0;
    }
    

    if(argc<2) // according to the point before, better y3 or <4
    {
        printf("Too few command line arguments");
        return 1; // not 0; 0 would mean success
    }
    
于 2013-04-30T16:36:48.580 回答
1

Joachim Pileborg 的回答显然是正确的,只需尝试将您的程序运行为

./a.out a \> b

以防止外壳将“>”解释为重定向。

于 2013-04-30T18:09:36.200 回答