我正在尝试将一个名为 data1 的数据文件重定向到我的程序中,但我不断得到一个segmentation fault
.
当我尝试./w data1
时,它会正确读取它,但是当我这样做时,会./w < data1
弹出错误。
我必须使用第二种方式来完成我的任务。
这是我的代码的样子:
int main(int argc, char *argv[])
{
FILE *Q;
Q = fopen(argv[1],"r");
}
我正在尝试将一个名为 data1 的数据文件重定向到我的程序中,但我不断得到一个segmentation fault
.
当我尝试./w data1
时,它会正确读取它,但是当我这样做时,会./w < data1
弹出错误。
我必须使用第二种方式来完成我的任务。
这是我的代码的样子:
int main(int argc, char *argv[])
{
FILE *Q;
Q = fopen(argv[1],"r");
}
argv[1]
指向你的二进制文件的第一个参数(没有它的名字),所以如果./w < data1
它丢失了。您正在尝试访问“非法”内存,因此您遇到了段错误。
该标记<
是 bash 功能,它不会传递给 C。
如果你想使用这样的重定向,只需从标准输入中读取而不关心文件/argv。这意味着“获取文件 data1 并将其传递给描述符 0,即标准输入”。
您可以使用scanf
或read(0, ...)
使用文件的内容。
使用 时./w < data1
,您无需打开文件。刚刚从stdin
.
您的第一个命令起作用的原因是您为程序提供了一个参数(在您的情况下是文件名),并且您的程序使用该参数打开文件。
当您使用重定向时,您正在将标准输入和标准输出(通过gets 和printf 等函数访问)重定向到文件,因此您根本不必在程序中打开任何文件。
您发出的第二个命令将文件的内容重定向到程序的标准输入。这意味着两件事,首先您需要从标准输入 (scanf) 读取数据,并且 argv[1] 将是未定义的。
因此,要回答您的问题,您正在尝试打开一个未定义的值,该值会转换为一个指针,从而导致您的崩溃
当您的程序以重定向开始时,文件已经打开。您可以从名为“stdin”的流中读取它。在这种情况下,您使用的是指向不存在的东西 (argv[1]) 的指针,这就是它失败的原因。
许多 C 函数默认使用标准输入,因此您不必指定要读取的文件。
你应该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
,表示标准输入。
有时您想不提供任何参数并使用标准输入,有时您想打开一个文件。这是你想要做的,
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
}