when compile code, no errors. however, when attempt run it, segmentation fault (core dumped). here main:
original code
void main(int argc, char *argv[]){ if(argc < 3){ return; } char *stop_list_name = argv[1]; char *doc_names[argc - 2]; int i; for(i = 0; < argc; i++){ doc_names[i] = argv[i]; } //create array of stop words char *stopwords[50]; char *word; int word_counter = 0; file *fp; fp = fopen(stop_list_name, "r"); if(fp != null){ while(!feof(fp)){ fscanf(fp, "%s", word); stopwords[word_counter] = word; word_counter++; } } fclose(fp); for(i = 0; stopwords[i] != '\0'; i++){ printf("%s", stopwords[i]); } }
i'm pretty sure wrong in while
loop, don't know what, or how fix it.
amended code
after seeing answers, modified code looks this, still crashes. what's wrong now?
int main(int argc, char *argv[]){ if(argc < 3){ return; } char *stop_list_name = argv[1]; char *doc_names[argc - 2]; int i; for(i = 2; < argc; i++){ doc_names[i-2] = argv[i]; } //create array of stop words enum {max_stop_words = 50}; char *stopwords[max_stop_words]; int word_counter = 0; file *fp = fopen(stop_list_name, "r"); if(fp != null){ char word[64]; int i; for(i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++){ stopwords[i] = strdup(word); } word_counter = i; fclose(fp); } for(i = 0; stopwords[i] != '\0'; i++){ printf("%s", stopwords[i]); } }
problems in original code
one possible source of problems is:
char *doc_names[argc - 2]; int i; for(i = 0; < argc; i++){ doc_names[i] = argv[i]; }
you allocate space argc-2
pointers , proceed copy argc
pointers space. that's buffer overflow (in case, stack overflow too). can cause trouble. plausible fix is:
for (i = 2; < argv; i++) doc_names[i-2] = argv[i];
however, don't need copy argument list; can process arguments index 2 end. note code shown doesn't use doc_names
, out-of-bounds assignment can still cause trouble.
you not allocating space read word into, nor allocating new space each stop word, nor ensure not overflow bounds of array in you're storing words.
consider using:
enum { max_stop_words = 50 }; char *stopwords[max_stop_words]; int word_counter = 0; file *fp = fopen(stop_list_name, "r"); if (fp != null) { char word[64]; (i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++) stopwords[i] = strdup(word); word_counter = i; fclose(fp); }
this diagnosed problem plausible cause of crash. used i
(declared earlier in code) in loop because word_counter
makes loop control line long so.
strictly, strdup()
not part of standard c, part of posix. if don't have posix, can write own:
#include <stdlib.h> #include <string.h> char *strdup(const char *str) { size_t len = strlen(str) + 1; char *result = malloc(len); if (result != 0) memmove(result, str, len); return result; }
you have other bad practices on display:
while (!feof(file))
wrong.- what should
main()
return in c , c++? - you should call
fclose(fp)
iffopen()
worked, need movefclose()
insideif
statement body.
problems in amended code
there's 1 important , couple of minor problems in amended code:
your loop prints stop words depends on null pointer (curiously spelled
'\0'
— valid unconventional spelling null pointer), initialization code doesn't set null pointer.there (at least) 2 options fixing that:
add null pointer:
(i = 0; < max_stop_words-1 && fscanf(fp, "%63s", word) == 1; i++) stopwords[i] = strdup(word); stopwords[i] = 0; fclose(fp); } (i = 0; stopwords[i] != '\0'; i++) printf("%s\n", stopwords[i]);
note upper bound
max_stop_words - 1
.or can use
wordcount
instead of condition:for (i = 0; < wordcount; i++) printf("%s\n", stopwords[i]);
i'd choose second option.
one reason doing avoids warnings
wordcount
being set , not used — minor problem.and
doc_names
set not used.
i worry because default compiler options generate errors unused variables — code doesn't compile until fix it. leads to:
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "usage: %s stop-words docfile ...\n", argv[0]); return 1; } char *stop_list_name = argv[1]; char *doc_names[argc - 2]; int i; (i = 2; < argc; i++) { doc_names[i - 2] = argv[i]; } int doc_count = argc - 2; // create array of stop words enum { max_stop_words = 50 }; char *stopwords[max_stop_words]; int word_counter = 0; file *fp = fopen(stop_list_name, "r"); if (fp != null) { char word[64]; int i; (i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++) stopwords[i] = strdup(word); word_counter = i; fclose(fp); } (i = 0; < word_counter; i++) printf("stop word %d: %s\n", i, stopwords[i]); (i = 0; < doc_count; i++) printf("document %d: %s\n", i, doc_names[i]); return 0; }
and, given stop words file containing:
help able may can should antonym prozac
and compiling (source file sw19.c
, program sw19
) with:
$ gcc -o3 -g -std=c11 -wall -wextra -wmissing-prototypes -wstrict-prototypes \ > -wold-style-definition -werror sw19.c -o sw19
and running as:
$ ./sw19 stopwords /dev/null stop word 0: stop word 1: able stop word 2: may stop word 3: can stop word 4: stop word 5: should stop word 6: stop word 7: antonym stop word 8: prozac document 0: /dev/null $