陷入fscanf循环

时间:2013-03-15 20:52:14

标签: c

程序的目的是获取2个文件,一个字典,另一个是文本,创建一个输出文件,并在其中输入文本文件中的所有单词,但是将大小写中的单词大写字典。

当我运行程序时,它一直在询问输入,所以我似乎陷入了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));
     }

2 个答案:

答案 0 :(得分: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循环条件后的多余分号。

答案 1 :(得分: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++;