0

我一直在研究这段代码,但我无法找出问题所在。该程序确实可以编译并运行,但最终会出现致命错误。

该程序读取一个文件并收集数字以计算总数(在将它们转换为浮点数之后)。然后它读取文件并显示小于 10.00 的文件

我有一个名为 myFile.txt 的文件,其内容如下:

詹姆斯----- 07.50 安东尼--- 17.00

所以显示应该是

  1. 总数为 24.50
  2. 这是小于 10.00 的那个:
  3. 詹姆斯 07.50

这是代码:

int main()
{
   int n =2, valueTest=0,count=0;
   FILE* file = NULL;
   float temp= 00.00f, average= 00.00f, flTen = 10.00f;
   float *totalNote = (float*)malloc(n*sizeof(float));

   int position = 0;
   char selectionNote[5+1], nameBuffer[10+1], noteBuffer[5+1];

   file = fopen("c:\\myFile.txt","r");
   fseek(file,10,SEEK_SET);
   while(valueTest<2)
   {
       fscanf(file,"%5s",&selectionNote);
       temp = atof(selectionNote);
       totalNote[position]= temp;
       position++;

       valeurTest++;
   }

   for(int counter=0;counter<2;counter++)
  {
          average += totalNote[counter];
  }
  printf("The total is : %f \n",average);

  rewind(file);
  printf("here is the one with less than 10.00 :\n");

  while(count<2)
  {
        fscanf(file,"%10s",&nameBuffer);

        fseek(file,10,SEEK_SET);
        fscanf(file,"%5s",&noteBuffer);
        temp = atof(noteBuffer);

        if(temp<flTen)
        { 
           printf("%s who has %f\n",nameBuffer,temp);
        }
        fseek(file,1,SEEK_SET);
        count++;
   }
   fclose(file);

}

我对 c 很陌生,发现它比 c# 或 java 更难。我想得到一些建议来帮助我变得更好。我认为这段代码可能更简单。你也这么认为吗?

4

3 回答 3

1

你没有提到你正在使用什么平台和编译器。鉴于您的文件名使用 Windows 样式的路径,我将猜测 MSVC 和 Windows。

您说代码可以编译并运行,但是您是否打开了编译器的警告?这可能会为您提供更多关于您可能正在做的可能不正确的事情的线索。

在修复了一些拼写错误并添加了标准包含头文件后,我在 gcc 中编译了您的代码,该代码警告了fscanf格式字符串和参数之间的不匹配。特别是,您正在传递一个指向char数组的指针,这不是您的意思。您可能想阅读 C 中的数组和指针,例如C FAQ。该文档中的其他条目也非常有启发性。

于 2010-12-29T20:35:49.707 回答
0

最有可能的是,您的致命错误来自声明

fscanf(file,"%5s",&selectionNote); 

通常,数组类型的表达式 likeselectionNote将隐式转换为指针类型(见注 1),因此在这种情况下&不需要:

fscanf(file, "%5s", selectionNote);

您没有解释代码应该做什么,所以我不确定如何告诉您如何重构它。


  1. 除非它是运算sizeof符或一元&运算符的操作数,或者是用于初始化数组的字符串字面量,否则类型为 ''array of type'' 的表达式将转换为类型为 ''pointer to type' 的表达式' 指向数组对象的初始元素并且不是左值。如果数组对象具有寄存器存储类,则行为未定义。-- C 语言标准(草案n1256),第 6.3.2.1 节,第 3 段。
于 2010-12-29T20:52:07.630 回答
0
  1. 不要使用fscanf后跟,而是使用带有合适格式字符串 ( )atof的单个:fscanf%f

    fscanf(file, "%f", &totalNote[position]);
    
  2. 您可以使用fscanffor 循环终止的返回值,而不是使用变量valueTest和常量2

    while(fscanf(file, "%f", &totalNote[position]) != 0)
    ...
    
  3. 从文件读取的第一个循环必须扫描名称和数字,即使您只需要数字!

  4. 您可以在读取它们的同一循环中累积数字。如果你这样做,你可以删除数组totalNote(如果你认为你会扩展你的代码来用数字做其他事情,而不仅仅是计算总数,那么这种“简化”是不合适的)

  5. 读取文件的第二个循环(之后的那个rewind)用for比表示更好while

    for (count = 0; count < counter; count++)
    ...
    
  6. 在同一个循环中,您绝对不需要使用fseek! 它把你的代码弄乱了,所以它只会从文件中读取“James”,而永远不会进入“Anthony”

  7. 您可能希望在打印名称之前从名称中删除“----”填充;你可以用strchror来做strtok

    fscanf(file,"%10s",&nameBuffer);
    strtok(nameBuffer, "-");
    
于 2010-12-29T21:58:18.107 回答