开发者

C : files manipulation Can't figure out how to simplify this code with files manipulation

I have been working on this code but I can't find out what is wrong. This program does compile and run but it ends up having a fatal error.

The program reads a file and collect the numbers in order to calculate the total (after having converted them to float). Then it reads the file and display the one that has less than 10.00

I have a file called myFile.txt, with the following content :

James------ 07.50 Anthony--- 17.00

So the display should be

  1. The total is 24.50
  2. Here is the one with less th开发者_开发技巧an 10.00 :
  3. James who has 07.50

And here is the code :

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);

}

I am pretty new to c and find it more difficult than c# or java. And I woud like to get some suggestions to help me to get better. I think this code could be simplier. Do you think the same ?


You don't mention what platform and compiler you're using. I'm going to guess MSVC and Windows, given that your filename uses a Windows-style path.

You say that the code compiles and runs but have you turned on the warnings from your compiler? That might give you more clues about potentially incorrect things you may be doing.

After fixing some of the typos and adding the standard include headers, I compiled your code in gcc which warned about mismatches between the fscanf format strings and the arguments. In particular, you are passing a pointer to the char arrays which is not what you mean. You may want to read up about arrays and pointers in C, e.g. in the C FAQ. The rest of the entries in that document are very enlightening as well.


Most likely, your fatal error is coming from the statement

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

Normally, an expression of array type like selectionNote will implicitly be converted to a pointer type (see note 1), so in this case the & is not necessary:

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

You don't explain what the code is supposed to be doing, so I'm not exactly sure how to tell you how to restructure it.


  1. Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined. -- C Language Standard (draft n1256), section 6.3.2.1, paragraph 3.


  1. Instead of using fscanf followed by atof, use a single fscanf with a suitable format string (%f):

    fscanf(file, "%f", &totalNote[position]);
    
  2. You can use the return value from fscanf for loop termination, instead of using the variable valueTest and the constant 2:

    while(fscanf(file, "%f", &totalNote[position]) != 0)
    ...
    
  3. The first loop that reads from file must scan both the names and the numbers, even though you need only numbers!

  4. You can accumulate the numbers in the same loop that reads them. If you do that, you can remove the array totalNote (this "simplification" is not suitable if you think you will extend your code to do other things with the numbers, not just calculate the total)

  5. The second loop that reads the file (the one after rewind) is better expressed with for than while:

    for (count = 0; count < counter; count++)
    ...
    
  6. In the same loop, you absolutely don't need to use fseek! It messes your code up, so it will only read "James" from the file, and never proceed to "Anthony"

  7. You probably want to remove the "----" padding from the names before printing them; you can do it with strchr or strtok:

    fscanf(file,"%10s",&nameBuffer);
    strtok(nameBuffer, "-");
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜