2013-03-15 47 views
0

该程序的要点是采取2个文件,一个字典,另一个是文本,创建一个输出文件,并把它放在文本文件中的所有单词,但大写的单词不存在于字典中。卡在fscanf循环

当我运行程序时,它一直要求输入,所以它似乎卡在fscanf循环中。而我只有3个fscanf循环。它必须是其中之一,但我无法弄清楚是哪一个以及为什么。

 #include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 
    #include <errno.h> 
    #include <ctype.h> 

    #define wosi 20 
    int comp (const void *a, const void *b); 

    int main(int ac, char *av[]) 
    { 
     int wordcount,i; 
     FILE *infi, *outfi; 
     char nothing, *dicptr, fina[100],letter[wosi]; 
     unsigned char c; 
     /*to return error in case number of arguments mismatch*/ 
     if (ac!=3) 
     { 
      fprintf (stderr," prog3: Man, I need 3 arguments to work!\n"); 
      return (1); 
     } 
      /*first fscanf loop*/ 
     while ((fscanf(infi,"%s",&nothing)!=0)) 
      wordcount++; 
     /* end of step 2 */ 
     dicptr = malloc(wordcount * wosi); 
     /* end of step 3*/ 

     rewind(infi); 
      /*second fscanf loop */ 
     for (i=0; fscanf(infi,"%s",&dicptr[i*wosi]) ;i++){} 

     /* this is qsort stage (finishing step 4) */ 

     qsort (dicptr,wordcount,wosi,comp); 

     /*step 5 */ 
     fclose (infi); 
     infi = fopen(av[2],"r"); 

     if (infi == NULL) 
     { 
      perror("opening"); 
      fprintf(stderr,"Can't open %s, the file is empty\n",av[2]); 
      return(1); 
     } 
     /*step 6 here */ 

     strcpy(fina, av[2]); 
     strcat(fina, ".out"); 

     outfi = fopen(fina, "w"); 

     /*step 7*/ 
      /* third fscanf loop */ 
     while((fscanf(infi, "%s", letter)!= EOF)); 
     { 
      for(i=0; letter[i]!='\0' ;i++) 
      { 
       c=letter[i]; 
       letter[i]= toupper(c); 
      } 

      if(bsearch(letter,dicptr,wordcount,wosi,comp)) 
      { 
       for(i=0;letter[i]!='\0';i++) 
       { 
        c=letter[i]; 
        letter[i]= tolower(c); 
       } 
      } 

      /* fputs to print in out file*/ 
      for(i=0; letter[i];i++) 
      { 
       fprintf(outfi,"%s",letter); 
      } 
     } 
     free(dicptr); 
     return (0); 
    } 

    int comp (const void *a, const void *b) 
    { 
     return (strcmp((const char *) a, (const char*) b)); 
    } 
+0

http://stackoverflow.com/q/15440488/1758762 – duDE 2013-03-15 20:54:02

+0

任何你可以计算出每个循环之前和之后打印标记到stderr的循环的机会? – 2013-03-15 20:54:19

+0

我试过把打印标记和问题仍然是相同的。 – 2013-03-15 21:06:15

回答

2

这不是CodeReview.SE,所以我只给出一些提示。

首先,我敢打赌,你不使用-Wall编译器标志编译:

h2co3-macbook:~ h2co3$ clang -Wall -o baz baz.c 
baz.c:24:14: warning: variable 'wordcount' is uninitialized when used here 
     [-Wuninitialized] 
     wordcount++; 
     ^~~~~~~~~ 
baz.c:12:23: note: initialize the variable 'wordcount' to silence this warning 
    int wordcount,i; 
      ^
       = 0 
baz.c:23:25: warning: variable 'infi' is uninitialized when used here 
     [-Wuninitialized] 
    while ((fscanf(infi,"%s",&nothing)!=0)) 
      ^~~~ 
baz.c:13:20: note: initialize the variable 'infi' to silence this warning 
    FILE *infi, *outfi; 
     ^
      = NULL 
2 warnings generated. 

其次,你的意思是使用comp()功能比较字符或字符串?如果是前者:

return *(const char *)a - *(const char *)b; 

如果是后者:

return strcmp(*(const char **), *(const char **)b); 

你似乎也有一些语法错误,如while循环的条件后的多余的分号。

+0

_“你似乎也有一些语法错误,如多余的分号后while循环的条件。“_ - 很好的接收! – 2013-03-15 21:06:13

+0

@SeanBright对于你也是:)(是不是你真的得到了那一个更早?) – 2013-03-15 21:08:08

+0

感谢您的回复,我已经使用了-Wall(我正在使用腻子) – 2013-03-15 21:08:15

0

此:

/*first fscanf loop*/ 
while ((fscanf(infi,"%s",&nothing)!=0)) 
    wordcount++; 

这个循环只有在fscanf()发现输入不使用%s转换结束。那么......基本上所有的东西都会用%s进行转换,所以这会读取整个文件,由空白分隔。最后,fscanf()将返回EOF,但EOF < 0,所以它仍然不会打破你的循环。你可能想比较反对EOF

/*first fscanf loop*/ 
while ((fscanf(infi,"%s",&nothing)!=EOF)) 
    wordcount++; 

这并不地址的事实,nothingchar和溢出。没有数组和字段宽度的明确限制,此方法是不安全的。既然你不关心存储也无妨,不过,有一个特殊的情况下,你可以告诉fscanf()%*s丢弃它:

/*first fscanf loop*/ 
while ((fscanf(infi,"%*s")!=EOF)) 
    wordcount++;