C: манипулирование файлами Не могу понять, как упростить этот код с манипулированием файлами - PullRequest
0 голосов
/ 29 декабря 2010

Я работал над этим кодом, но не могу выяснить, что не так.Эта программа компилируется и запускается, но заканчивается фатальной ошибкой.

Программа читает файл и собирает числа, чтобы вычислить итоговое значение (после преобразования их в число с плавающей точкой).Затем он читает файл и отображает файл, у которого меньше 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.И я хотел бы получить некоторые предложения, которые помогут мне стать лучше.Я думаю, что этот код может быть проще.Ты думаешь так же?

Ответы [ 3 ]

1 голос
/ 29 декабря 2010

Вы не упоминаете, какую платформу и компилятор вы используете. Я собираюсь угадать MSVC и Windows, учитывая, что ваше имя файла использует путь в стиле Windows.

Вы говорите, что код компилируется и запускается, но вы включили предупреждения от вашего компилятора? Это может дать вам больше подсказок о потенциально неправильных вещах, которые вы, возможно, делаете.

После исправления некоторых опечаток и добавления стандартных заголовков include я скомпилировал ваш код в gcc, который предупреждал о несоответствии между строками формата fscanf и аргументами. В частности, вы передаете указатель на массивы char, который вы не имеете в виду. Вы можете прочитать о массивах и указателях в C, например, в C FAQ . Остальные записи в этом документе также очень поучительны.

0 голосов
/ 30 декабря 2010
  1. Вместо использования fscanf с последующим atof используйте один fscanf с подходящей строкой формата (%f):

    fscanf(file, "%f", &totalNote[position]);
    
  2. Вы можете использовать возвращаемое значение из fscanf для завершения цикла вместо использования переменной valueTest и константы 2:

    while(fscanf(file, "%f", &totalNote[position]) != 0)
    ...
    
  3. Первый циклПри чтении из файла необходимо сканировать как имена, так и числа, даже если вам нужны только цифры!

  4. Числа можно накапливать в том же цикле, который их читает.Если вы сделаете это, вы можете удалить массив totalNote (это «упрощение» не подходит, если вы думаете, что вы будете расширять свой код, чтобы выполнять другие операции с числами, а не просто вычислять сумму)

  5. Второй цикл, который читает файл (тот, что после rewind), лучше выражается с for, чем while:

    for (count = 0; count < counter; count++)
    ...
    
  6. В том жецикл, вам абсолютно не нужно использовать fseek!Он испортил ваш код, поэтому он будет только читать «Джеймс» из файла и никогда не перейдет к «Энтони»

  7. Возможно, вы захотите удалить заполнение "----"от имен до их печати;Вы можете сделать это с помощью strchr или strtok:

    fscanf(file,"%10s",&nameBuffer);
    strtok(nameBuffer, "-");
    
0 голосов
/ 29 декабря 2010

Скорее всего, ваша фатальная ошибка исходит из утверждения

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

Обычно выражение типа массива, такое как selectionNote, неявно преобразуется в тип указателя (см. Примечание 1), поэтому в этом случае & не требуется:

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

Вы не объясняете, что должен делать код, поэтому я не совсем уверен, как вам сказать, как его реструктурировать.


  1. За исключением случаев, когда это операнд оператора sizeof или унарный оператор & или строковый литерал, используемый для инициализации массива, выражение с типом 'массив типа' 'преобразуется в выражение с типом '' указатель на тип '', которое указывает на начальный элемент объекта массива и не является lvalue. Если объект массива имеет класс хранения регистров, поведение не определено. - Стандарт языка С (черновик n1256 ), раздел 6.3.2.1, пункт 3.
...