Перейти к содержанию
    

Чтение из файла данных на си

Добрый день.

 

Есть файл file.dat

 

Не могу из него считать числа. Необходимо считывать по 4096 чисел.

 

Вот что у меня на данный момент.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(void)
{
   int i = 0;
   char arr[20];
   double S[4096];
   FILE *file;

   if((file = fopen("file.dat", "r")) == NULL)
   {
       puts("File could not be found");
       return 1;
   }

   while ((fgets(arr, 20, file) != NULL) && i < 4096)
   {


       fseek (file,21*(i+2)-20,SEEK_SET); //Здесь вся проблема. Когда i = 4096, обнуляю i. Опять с самого начала файла читает 4096 чисел. Как решить эту проблему нет идей
       double c = atof(arr);
       printf("%.4f\n", c);
       S[i] = c;


       if(i == 4096)
       {
           i = 0;
       }

   }

   fclose(file);

   return 0;
}

 

file.dat загрузить не получилось. Он генерится в матлабе:

dlmwrite('file.dat', A(repeat,:), '-append', 'delimiter', ' ', 'precision', '%20.4f')

Просто скину пару значений:

              0.0000               1.6406               3.5000               5.4063             100.2813             100.5625
              0.0000               1.8906               3.2969               4.8594              99.6094              99.5781
              0.0000               1.4219               3.0313               4.6563             101.3594             101.1875

Т.е. необходимо считывать первую строку, потом вторую и т.д. Если важно, то в каждой строке 8192 элемента

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. необходимо считывать первую строку, потом вторую и т.д. Если важно, то в каждой строке 8192 элемента

У Вас не изменяется значение индекса i.

Программа должна зациклиться на постоянном чтении 19-ти байт начиная с 22-го байта файла.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смешалось все в кучу...

Зачем fseek? Ничего, что он задает смещение безразлично к пробелам и '\n'?

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

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

Т.е. алгоритм такой: 1) mmap файла на буфер, 2) пробегаемся strtod по буферу, контролируя значение endptr, и считываем свои 4096 чисел (ну или меньше, если файл вдруг раньше кончится).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А чем вас не устроил в доску стандартный и простой (как та же доска) fscanf ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас не изменяется значение индекса i.

Программа должна зациклиться на постоянном чтении 19-ти байт начиная с 22-го байта файла.

 

Описка. Перед if(i == 4096) должно быть i++

 

А чем вас не устроил в доску стандартный и простой (как та же доска) fscanf ?

 

Не взлетело. Может как-то данные надо по-другому сформировать. Да я в курсе, что fscanf читает до пробела. Пробовал формировать данные через запятую, но fscanf меня послал

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да я в курсе, что fscanf читает до пробела. Пробовал формировать данные через запятую, но fscanf меня послал

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да я в курсе, что fscanf читает до пробела.

fscanf может все данные в передаваемой строке положить в переменные вот пример:

 

fscanf(fp,"%s%d%d%d", name2, &a_code, &b_code, &c_code);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смешалось все в кучу...

Зачем fseek? Ничего, что он задает смещение безразлично к пробелам и '\n'?

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

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

Т.е. алгоритм такой: 1) mmap файла на буфер, 2) пробегаемся strtod по буферу, контролируя значение endptr, и считываем свои 4096 чисел (ну или меньше, если файл вдруг раньше кончится).

 

С помощью fseek пытался передвигаться к началу нового числа.

Спасибо за инфу! Про mmap и его быстродействие не знал. Очень познавательно было :a14:

 

fscanf может все данные в передаваемой строке положить в переменные вот пример:

 

fscanf(fp,"%s%d%d%d", name2, &a_code, &b_code, &c_code);

 

Это хорошо, когда у есть не очень большое число столбцов. Пример здесь: http://sernam.ru/lect_matlab.php?id=22

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...