i'm developing a program that should read line from a file and retrieve information manipulating them. The file in question is:
WORD abc
TOTAL 10
FILE /home/user/Scrivania/find/try
OCCURRENCES 2
0 0
1 0
FILE /home/user/Scrivania/find/try1
OCCURRENCES 2
3 0
4 0
FILE /home/user/Scrivania/prova/prova1/prova3/try3
OCCURRENCES 3
2 0
3 0
4 0
FILE /home/user/Scrivania/prova/try4
OCCURRENCES 3
2 0
3 0
4 0
WORD ac
TOTAL 10
FILE /home/user/Scrivania/find/try
OCCURRENCES 3
2 0
3 0
4 0
FILE /home/user/Scrivania/find/try1
OCCURRENCES 3
0 0
1 0
2 0
FILE /home/user/Scrivania/prova/prova1/prova3/try3
OCCURRENCES 2
0 0
10
FILE /home/user/Scrivania/prova/try4
OCCURRENCES 2
0 0
1 0
I use this method:
void getWordOccurences(char *word, char *file, char *fileToCheck){
FILE *f;
char *curr = NULL;
size_t len = 0;
ssize_t line_size;
char *currentWord = NULL;
char *currentFile = NULL;
char *p = NULL;
int check = 0;
if(fileToCheck == NULL){
printf("Pass a file as arguments\r\n");
}else{
f = fopen(file, "r");
if(f == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", file);
exit(1);
}
while((line_size = getline(&curr, &len, f)) != -1){
trimTrailing(curr);
if(curr[0] == 'W'){
currentWord = (char*)malloc((strlen(curr)+1)*sizeof(char));
strcpy(currentWord, strchr(curr, ' '));
currentWord++;
continue;
}
if(curr[0] == 'F'){
currentFile = (char*)malloc((strlen(curr)+1)*sizeof(char));
strcpy(currentFile, strchr(curr, ' '));
currentFile++;
continue;
}
if(curr[0] == 'O'){
p = (char*)malloc((strlen(curr)+1)*sizeof(char));
strcpy(p, strchr(curr, ' '));
p++;
continue;
}
if(strcmp(currentWord, word) == 0){
if(strcmp(currentFile, fileToCheck) == 0){ // LINE 414
if(atoi(p) > 0){
check = 1;
printf("%s \n", curr);
continue;
}
}
}
}
if(check == 0){
printf("The word %s doesn't occur in the file %s \n", word, fileToCheck);
}
fclose(f);
}
}
I pass to this method the parameters as input argunents. The variable word
store to word to search, file
store the path of the file to open (in this case, the file showed above) and fileToCheck
is the file path to be searched inside the file (the one immediately after FILE
).
I can pass every string i want as input arguments in the variable word
except of abc
. Only if i pass abc
i get: (valgrind running)
==2447== Invalid read of size 1
==2447== at 0x4FA5D60: __strcmp_ssse3 (strcmp.S:144)
==2447== by 0x10A21D: getWordOccurences (find.c:414)
==2447== by 0x108F3E: main (find.c:44)
==2447== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Segmentation fault (core dumped)
I don't get why this happen only in i pass abc
as arguments.
In the main method i only call this function, nothing else:
int main(int argc, char * argv[]){
getWordOccurences(argv[1], argv[2], argv[3]);
return 0;
}
The running command is :
valgrind myprog abc inputFile /home/users/Scrivania/find/try
I know that Is caused by a null pointer in line 414, but why i pass 'ac' it works and not with 'abc'?
To solve the problem i added a control in the three if at the bottom:
if(currentWord != NULL && (strcmp(currentWord, word) == 0)){
if(currentFile != NULL && (strcmp(currentFile, fileToCheck) == 0)){
if(p != NULL && (atoi(p) > 0)){
check = 1;
printf("%s \n", curr);
continue;
}
}
}
And also i changed these portion of code:
strcpy(currentWord, strchr(curr, ' '));
currentWord++;
strcpy(currentFile, strchr(curr, ' '));
currentFile++;
strcpy(p, strchr(curr, ' '));
p++;
With these more performant lines:
sscanf(strchr(curr, ' '), "%s", currentWord);
sscanf(strchr(curr, ' '), "%s", currentFile);
sscanf(strchr(curr, ' '), "%s", p);