对不起所有的问题,但是当我运行此代码时,我的终端窗口上出现了“Segmentation fault(core dumped)”。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int usage (void) {
printf("Usage: head <file>\n");
printf(" Or: head <file> -n <number of characters>\n");
printf(" Or: head -n <number of characters> <file>\n");
return -1;
}
int main (int argc,char **argv) {
if ((argc != 2) && (argc != 4)) return usage();
char *fileName = argv[1];
int lineCount = 10;
FILE *src;
if ((argc == 4) && (strcmp(argv[1], "-n" != 0))){
fileName = argv[1];
lineCount = argv[3];
puts("-n in last position");
}else{
fileName = argv[3];
lineCount = argv[1];
puts("-n in first position");
}
if((src = fopen(fileName, "r")) == NULL){
puts("Can't open input file.");
exit(-1);
}
}
我很确定它与fopen函数有关,但我不确定为什么会发生这种情况。
答案 0 :(得分:6)
看起来如果argc == 2你立即访问argv [3]。那会受伤。
答案 1 :(得分:5)
首先出现了一些问题 - 比较是在函数内部
strcmp(argv[1], "-n" != 0)
您正在将char *分配给int
lineCount = argv[3];
在这里
lineCount = argv[1];
以下是我得到的编译错误
[adrian@iceweasel ~]$ gcc -Wall -ansi -pedantic uu.c
uu.c: In function ‘main’:
uu.c:15: warning: ISO C90 forbids mixed declarations and code
uu.c:19: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast
/usr/include/string.h:143: note: expected ‘const char *’ but argument is of type ‘int’
uu.c:21: warning: assignment makes integer from pointer without a cast
uu.c:25: warning: assignment makes integer from pointer without a cast
uu.c:33: warning: control reaches end of non-void function
答案 2 :(得分:1)
你在错误的地方有一个右括号:
(strcmp (argv[1], "-n" != 0))
应该是:
(strcmp (argv[1], "-n") != 0)
然而,即使一旦修复,你的论证处理仍然不太正确。
在your previous question中,head -n COUNT FILE
不可能,这使得论证检查相当容易。
以下是您需要遵循的逻辑,即您允许“浮动”-n count
部分:
int linecount
char *filename = NULL
if argc == 2:
linecount = 10
filename = argv[1]
else:
if argc == 4:
if argv[1] == "-n":
linecount = argv[2]
filename = argv[3]
else:
if argv[2] == "-n":
linecount = argv[3]
filename = argv[1]
if filename = NULL:
generate some error
它基本上首先捕获了两个参数版本。如果它是一个四参数版本,它会找出“-n”的位置,以便它可以智能地决定哪个参数是哪个值。
正如您所看到的那样,这并不是您所拥有的(您的代码在argv[1]
中查找的行数是从不的情况)。你应该使用这样的东西作为指南:
argc argv[0] argv[1] argv[2] argv[3]
---- ------- ------- ------- -------
2 head <file>
4 head <file> -n <count>
4 head -n <count> <file>
一旦你提到它,就应该很容易为不同的情况编写代码。
你必须将我的伪代码转回C当然(使用strcmp
而不是==
作为字符串,并确保使用atoi/strtol
来转换字符串linecount参数为整数),但这是你应该遵循的基本流程。
答案 3 :(得分:0)
您是否可以使用getopt()
功能?在Linux上,getopt()
函数将使用aplomb处理任一位置的-n
选项(除非设置了POSIXLY_CORRECT
环境变量)。它会让你的生活更轻松:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int numLines = 10;
char *fileName = 0;
int opt;
while ((opt = getopt(argc, argv, "n:")) != -1)
{
switch (opt)
{
case 'n':
numLines = atoi(optarg); /* Could check for positive answer */
break;
default:
usage(); /* Assuming usage() does not return */
break;
}
}
if (optind != argc - 1) /* Insist on one filename argument */
usage();
fileName = argv[optind];
...open file and process it...
return(0);
}
请注意,处理标准输入而不是文件很容易;当然,需要调整循环后的条件。您也可以轻松添加-?
或-h
选项以获取帮助,依此类推。