2013-03-15 72 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++;