2

我正在尝试将一个名为 data1 的数据文件重定向到我的程序中,但我不断得到一个segmentation fault.

当我尝试./w data1时,它会正确读取它,但是当我这样做时,会./w < data1弹出错误。

我必须使用第二种方式来完成我的任务。

这是我的代码的样子:

int main(int argc, char *argv[])
{
 FILE *Q;
 Q = fopen(argv[1],"r");
}
4

7 回答 7

4

argv[1]指向你的二进制文件的第一个参数(没有它的名字),所以如果./w < data1它丢失了。您正在尝试访问“非法”内存,因此您遇到了段错误。

该标记<是 bash 功能,它不会传递给 C。

如果你想使用这样的重定向,只需从标准输入中读取而不关心文件/argv。这意味着“获取文件 data1 并将其传递给描述符 0,即标准输入”。

您可以使用scanfread(0, ...)使用文件的内容。

于 2013-10-21T20:56:59.010 回答
2

使用 时./w < data1,您无需打开文件。刚刚从stdin.

于 2013-10-21T20:57:16.790 回答
2

您的第一个命令起作用的原因是您为程序提供了一个参数(在您的情况下是文件名),并且您的程序使用该参数打开文件。

当您使用重定向时,您正在将标准输入和标准输出(通过gets 和printf 等函数访问)重定向到文件,因此您根本不必在程序中打开任何文件。

于 2013-10-21T21:01:01.487 回答
0

您发出的第二个命令将文件的内容重定向到程序的标准输入。这意味着两件事,首先您需要从标准输入 (scanf) 读取数据,并且 argv[1] 将是未定义的。

因此,要回答您的问题,您正在尝试打开一个未定义的值,该值会转换为一个指针,从而导致您的崩溃

于 2013-10-21T20:58:15.660 回答
0

当您的程序以重定向开始时,文件已经打开。您可以从名为“stdin”的流中读取它。在这种情况下,您使用的是指向不存在的东西 (argv[1]) 的指针,这就是它失败的原因。

许多 C 函数默认使用标准输入,因此您不必指定要读取的文件。

于 2013-10-21T21:00:04.357 回答
0

你应该FILE*像这样初始化你的变量:

FILE *Q; 
if (argc >= 2) {
    // at least one argument given, try to open it as file
    Q = fopen(argv[1],"r");
    // let's add error checking while we're at it!
    if (!Q) {
        perror("fopen");
        return 1; // note: this only works if this code is in main function
    }
} else {
    Q = stdin;
}

现在 Q 要么是作为命令行参数给出的文件,要么是stdin,表示标准输入。

于 2013-10-21T21:02:51.017 回答
0

有时您想不提供任何参数并使用标准输入,有时您想打开一个文件。这是你想要做的,

int main(int argc, char *argv[])
{
    FILE *Q = stdin; //use stdin unless you provide a filename
    if( (argc>1 ) && strcmp(argv[1],"-") ) { //allow "-" as alias for stdin
        if( !(Q = fopen(argv[1],"r")) ) {
            printf("Error, cannot open %s\n",argv[1]);
            exit(1);
        }
    }
    //read from Q here
}
于 2013-10-21T21:11:48.120 回答