c язык: читать содержимое файла как числа и складывать их вместе - PullRequest
1 голос
/ 01 декабря 2010

У меня есть следующее в текстовом файле с именем: values.txt

1 4 
2.5 3.76
122 10
277.543 
165.4432

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

1 Pair:(1, 4) = 5

2 Pair:(2.5, 3.76)= 6.26

и т. Д. *

Я открываю файл вот так

int c;
FILE myfile; 

myfile= fopen("values.txt", "r"); 
if ( myfile == NULL ) { 
  printf("Cannot open TEXT file\n");
  return 1; 
}

double aa,bb;
while ( (c = getc(myfile) ) != EOF ) { 
    // HERE SHOULD I DO THE OUTPUT BUT HOW?
}

Любая помощь очень ценится.

Язык = C

Ответы [ 5 ]

2 голосов
/ 01 декабря 2010

Следующий код делает то, что вы ожидаете.myfile должен быть объявлен как FILE *.fopen возвращает указатель на структуру FILE.Если файл очень большой, я бы порекомендовал читать в буферах большого размера (например, 65535 и т. Д.), Анализировать их как char по char и преобразовывать в плавающие значения.Это сокращает накладные расходы на системные вызовы, которые занимают больше времени, чем обработка текста для перемещения значений.

#include <stdio.h>
#include <string.h>

main(int argc, char *argv[])
{
    FILE* myfile; 

    myfile = fopen("values.txt", "r"); 
    if ( myfile == NULL ) { 
        printf("Cannot open TEXT file\n");
        return 1; 
    }

    double aa,bb;
    while (2 == fscanf(myfile, "%lf %lf", &aa, &bb)) {
        printf("%lf\n", aa+bb);
    }
    return 0;
}
0 голосов
/ 01 декабря 2010

в c ++ извините :( я не знаю, c

это очень простой логический код для простого минда: я тоже начинающий, я не тестировал эту прогу, извините, если что-то идет не так, но точно по тому же принципу работал мой парсер и он работал нормально. так что это верный метод. не очень эффективно, но ... не используйте эту программу сразу, поймите, что это логика, это вам очень поможет. копирование, которое не даст вам ничего ... преподаватели парсера такие редкие ....

int x = 0; char ch = 'r'; // Я использовал это уклонение, чтобы избежать ошибки при первом проверке чека. это должно быть заполнено чем-то, когда программа запускается. чёрный бигч [10]; int checknumber = 0;

float firstnumber = 0; второе число с плавающей запятой = 0; результат с плавающей запятой = 0;

void clearar (char frombigar [10], int xar) // эта функция получает bigch в качестве ссылки, что означает, что eny Изменения, сделанные здесь, напрямую влияют на саму бигчу. эта функция получает фактическую длину массива и ставит пробелы в каждом элементе bigch обнулять числа. нам нужно очистить Bigch любых предыдущих чисел. внизу вы увидите, зачем мне это нужно. «xar» - это x из основной функции. здесь, чтобы сказать нашему уборщику истинная длина заполненных бигаром элементов. { для (int i = 0; i }

}

int main () { <------------------- // здесь вы добавляете команды открытия и чтения файлов while (! myfile.eof ()) // пока не достигнут конец текстового файла { ч = myfile.get (); // переводит каждую букву в ch и делает курсор на один шаг переслать в текстовый файл для дальнейшего чтения. get () выполняет переадресацию курсора автоматически </p>

 if (ch!= "  ")                   //i used space as an indicator where one number ends
                                  //so while space havent been reahced, read letters.
    { bigch[x] = ch;              //get read letter into bigch array. 
      x++;                        //icrement bigch array step

    }
 else 

 if(ch == " ")             //if space is reached that means one number has ended and
  {                        im trying to set a flag at that moment. it will be used further.
    checknumber++;         the flag is simple number. first space will set checknumber to 1
                           second space will set it to 2. thats all.
  } 

  if (checknumber == 1)                      //if our checknumber is 1, wich means that reading  
                                             of first number is done, lets make one whole float              
                                             from that bigch array.

{firstnumber = atof (bigch); // здесь мы получаем команду bigch, atof (array to float) преобразует массив bigch в одно целое число с плавающей точкой.

   clearar(bigch,x);                             //here we send bigch and its element step into function where  
                                                 bigch gets cleaned because we dont want some ghost numbers in it.
                                                 abviously clearar function cleans bigch int main function aswell, 
                                                  not only in it's teritory. its a global cleaning :)
         }
    else if (checknumber ==2)                     //here we do the same but if flag is 2 this means that two spaces
                                                  had been passed and its time to convert bigch into secondnumber.
            { secondnumber = atof(bigch);          //same method of converting array into float (it hates other
                                                   not number letters, i mean if its a number its fine. if in your text
                                                   was 'a' or 's' in that case atof will panic hehe.. )
             clearar(bigch,x);                     //same thing, we send bigch to cleaner function to kill any numbers 
                                                    it, we get one space letter ( " " ) into each element of bigch.
            }

контрольный номер = 0; если оба числа были считаны и преобразованы. нам нужно сбросить космический флагер. и начните считать форму 0; для следующих парных номеров.

результат = первый номер + второй номер; ну тут все понятно. } } * * Тысяча двадцать-один

0 голосов
/ 01 декабря 2010

Вы не показали, что вам нужно в качестве вывода для строк с одним значением, но это выглядит как случай для fgets() и sscanf(), если вы действительно не хотите, чтобы две строки с одним значением обрабатывались как единица.

char buffer[256];
int rownum = 0;
while (fgets(buffer, sizeof(buffer), myfile) != 0)
{
    double aa, bb;
    int n = sscanf(buffer, "%lf %lf", &aa, &bb);
    if (n == 2)
        printf("%d Pair:(%g, %g) = %g\n", ++rownum, aa, bb, aa+bb);
    else if (n == 1)
        printf("%d Solo:(%g) = %g\n", ++rownum, aa, aa);
    else
    {
        printf("Failed to find any numbers in <<%s>>\n", buffer);
    }
}

Если вы используете fscanf(myfile, "%g %g", &aa, &bb), то он будет читать по новым строкам (они считаются пробелами) в поисках чисел, поэтому он будет читать одно число из одной строки, а второе - из другой строки. Обычно это не то, что нужно людям (но когда это то, что вам нужно, это чрезвычайно полезно). Восстановление после ошибок с fscanf() имеет тенденцию быть более опасным, чем с fgets() и sscanf().

0 голосов
/ 01 декабря 2010

выглядит как домашнее задание, но fscanf может прочитать строку в переменную, например:

int n;
fscanf (myfile,"%d",&n); 
0 голосов
/ 01 декабря 2010

Для этой простой задачи используйте

double a, b;
if (fscanf(myfile, "%lf %lf", &a, &b) == 2)
        printf("%f + %f = %f\n", a, b, a+b);
.
...