Reputation: 1130
Hi sorry for all the questions, but I am getting a "Segmentation fault(core dumped)" on my terminal window when I run this code.
#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);
}
}
I'm pretty sure it's with the fopen function, but I'm not exactly sure why this is happening.
Upvotes: 0
Views: 1489
Reputation: 881653
You have one of the closing parentheses in the wrong place:
(strcmp (argv[1], "-n" != 0))
should be:
(strcmp (argv[1], "-n") != 0)
However, even once that's fixed, your argument processing is still not quite right.
In your previous question, the head -n COUNT FILE
was not a possibility, that made the argument checking reasonably easy.
Here's the logic you need to follow now that you allow for a "floating" -n count
section:
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
It basically catches the two-argument version first. If it's a four-argument version, it then finds out where the "-n" is so it can intelligently decide which argument is which value.
As you can see, that's not quite what you have (your code looks for linecount in argv[1]
which is never the case). You should use something like this as a guide:
argc argv[0] argv[1] argv[2] argv[3]
---- ------- ------- ------- -------
2 head <file>
4 head <file> -n <count>
4 head -n <count> <file>
Once you refer to that, it should be easy to write the code for the different situations.
You'll have to turn that pseudo-code of mine back into C of course (using strcmp
instead of ==
for strings, and ensuring you use atoi/strtol
for converting the string linecount argument to an integer), but that's the basic flow you should follow.
Upvotes: 1
Reputation: 754110
Are you allowed to use the getopt()
function? On Linux, the getopt()
function would handle the -n
option in either location with aplomb (unless the POSIXLY_CORRECT
environment variable is set). It would make life easier for you:
#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);
}
Note that it would be easy to process standard input instead of a file; the condition after the loop would need to be adjusted, of course. You can also easily add a -?
or -h
option for help, and so on.
Upvotes: 0
Reputation: 23866
There are a few things wrong first off - the comparison is inside the function
strcmp(argv[1], "-n" != 0)
You are assigning an char * to a int
lineCount = argv[3];
And here
lineCount = argv[1];
Here are the compile errors I get
[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
Upvotes: 5
Reputation: 1786
it looks like if argc==2 you immediately access argv[3]. That's gotta hurt.
Upvotes: 6