【问题标题】:printf problems打印问题
【发布时间】:2014-10-02 02:12:36
【问题描述】:

嗨,我是 c 编程的新手,我需要打开一个文件,读取其内容,让程序记住它们,然后从那里提取有关员工的特定信息。这是文件的外观:(有 16 名员工)

Tremblay Alain A 35.0 35.5 
Vachon Jean P 40.0 22.75 
...
St-amour Flavie P 40.0 25.0 

我只需要让结果出现一次,但它出现了 16 次。我试图将 printf ( % d..​​., k) 放在 while 之外,但它不起作用。

#include <stdio.h>
struct employes 
{
  char nom[25];
  char prenom[25];
  char poste;
  float heures;
  float salaire;
};

int main()
{
   struct employes tab[16];
   FILE *fic;

   if ((fic = fopen("employes.txt","r"))== NULL)
   {
       printf("Error! opening file");
       exit(1);         /* Program exits if file pointer returns NULL. */
   }

   int choix;
   printf("1. Afficher le nombre de programmeurs qui travaillent plus de 45 heures / semaine \n"
          "2. Afficher le nombre d'opérateurs qui travaillent plus de 40.50 heures / semaine \n"
          "3. Afficher le nombre de secrétaires qui travaillent plus de 35.00 heures / semaine\n"
          "4. Sortir\n");
   scanf("%d",&choix);

   int ch;
   int i=0;
   int k=0;
   do
   {
   switch(choix)
   {
      case 1:  while ( (ch = fgetc(fic)) != EOF)
               {
                  fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                    if(tab[i].poste == 'P' && tab[i].heures >= 45.00)
                    k++;
                    printf(" %d programmeurs travaillent plus de 45.00 heures/semaine\n",k);
               }
               break;

      case 2:  while ( (ch = fgetc(fic)) != EOF)
               { 
                   fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                     if(tab[i].poste == 'O' && tab[i].heures>=40.50)
                     k++;
                     printf(" %d operateurs travaillent plus de 40.50 heures/semaine\n",k);
               } 
               break;

      case 3:  while ( (ch = fgetc(fic)) != EOF) 
               {
                   fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

                     if(tab[i].poste == 'S' && tab[i].heures>=35.00)
                     k++;
                     printf(" %d secretaires travaillent plus de 35.00 heures/semaine\n",k);
               } 
               break;

     case 4: printf("Au revoir!\n"); 
             break;
     default: printf("Desole, choix invalide.");
              break;

    }
}while(choix!=4);
   fclose(fic);



   system("pause");
   return 0;

}

程序打印这个:

1. Afficher le nombre de programmeurs qui travaillent plus de 45 heures / semain
e
2. Afficher le nombre d'opÚrateurs qui travaillent plus de 40.50 heures / semain
e
3. Afficher le nombre de secrÚtaires qui travaillent plus de 35.00 heures / sema
ine
4. Sortir
1
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine
0 programmeurs travaillent plus de 45.00 heures/semaine

但我希望它只打印一次这一行。

【问题讨论】:

  • 想法:验证您的输入stop using feof() in a loop condition.。我还质疑为什么int i每个案例块 中声明,从而隐藏了您可能关心的那个(它永远不会增加,也是一个错误)。
  • 您好,感谢您的评论,请问输入是什么意思?如果我不使用 feof() 这会起作用吗:while ( fgets ( tab, sizeof tab, fic ) != NULL ) 而不是我的 do while?
  • 我的意思是你永远不会检查fscanf 的结果来知道它刚刚为你解析了多少个参数。这很重要,因为否则你会盲目地假设它们解析正确。我提供了read the linked question,以了解在循环条件下错误使用feof 的正确替代方法。您在该评论中显示的内容看起来比您在问题中发布的内容好多。只要知道你会sscanf-ing 出行缓冲区,而不是fscanf-ing 出FILE*,如果你这样做的话。
  • 我会搜索如何做到的,谢谢,否则这会使程序工作吗?您是否看到其他可能有问题的地方?因为虽然它编译了我的程序并没有显示任何东西。
  • int ch; while ( (ch = fgetc(fic)) != EOF) 感谢您的链接,我使用了这个

标签: c file printf structure


【解决方案1】:

这一行,fscanf "%s %s %c %f %f" 的格式应该添加一个 '\n' 因为每个新项目之前都有一个新行。所以也许格式""%s %s %c %f %f\n" 是对的。

而且当你读取一个字符串时,不要使用 &

fscanf(fic,"%s %s %c %f %f", &tab[i].nom, &tab[i].prenom, &tab[i].poste, &tab[i].heures , &tab[i].salaire);

应该是

fscanf(fic,"%s %s %c %f %f\n", tab[i].nom, tab[i].prenom, &tab[i].poste, &tab[i] .heures, &tab[i].salaire);

【讨论】:

  • 它仍然没有显示任何东西:(当程序编译它只是说按任意键继续......
  • 我看到你使用while循环来控制进程,但是当你使用fgets时,会读取整行。
  • 您可以在您的 switch-case 中尝试 default 以查看程序是否到达它。
【解决方案2】:

实际上,我没有运行你的程序,但我猜你的 fscanf 应该是 fscanf(fic,"%s %s %c %f %f", tab[i].nom, tab[i] .prenom, &tab[i].poste, &tab[i].heures, &tab[i].salaire);

而linux man page中fgets的原型是char *fgets(char *s, int size, FILE *stream);

所以我认为你的 fgets 函数应该是 fgets(buff, 40, fic) 我找到的参考是http://linux.die.net/man/3/fgets

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多