реклама на сайте
подробности

 
 
 
Closed TopicStart new topic
> Чтение из файла данных на си, Необходимо считать числа из файла
shtunder
сообщение Mar 14 2017, 02:37
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 14-07-14
Пользователь №: 82 243



Добрый день.

Есть файл file.dat

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

Вот что у меня на данный момент.
CODE
#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 элемента
Go to the top of the page
 
+Quote Post
aiwa
сообщение Mar 14 2017, 03:32
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(shtunder @ Mar 14 2017, 04:37) *
Т.е. необходимо считывать первую строку, потом вторую и т.д. Если важно, то в каждой строке 8192 элемента

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


Go to the top of the page
 
+Quote Post
Эдди
сообщение Mar 14 2017, 05:18
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 436
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250



Смешалось все в кучу...
Зачем fseek? Ничего, что он задает смещение безразлично к пробелам и '\n'?
Если уж пользуете fgets, так считывайте сразу целую строку, сделав буфер достаточного размера, а после считывания при помощи strtod поочередно выкусывайте оттуда числа.
Я при работе с такими вещами делаю проще: mmap файла на строковый буфер, и работаю с ним как с большим текстом, а уж ведро само пусть разбирается, что ему откуда считать — и быстрей получается, и проще.
Т.е. алгоритм такой: 1) mmap файла на буфер, 2) пробегаемся strtod по буферу, контролируя значение endptr, и считываем свои 4096 чисел (ну или меньше, если файл вдруг раньше кончится).


--------------------
Я: на гитхабе, на stackexchange, в ЖЖшке
--------------------------------
In the world, only two things are the worst: Windows and Poettering.
Go to the top of the page
 
+Quote Post
XVR
сообщение Mar 14 2017, 10:14
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 956
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



А чем вас не устроил в доску стандартный и простой (как та же доска) fscanf ?
Go to the top of the page
 
+Quote Post
shtunder
сообщение Mar 14 2017, 12:19
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 14-07-14
Пользователь №: 82 243



Цитата(aiwa @ Mar 14 2017, 03:32) *
У Вас не изменяется значение индекса i.
Программа должна зациклиться на постоянном чтении 19-ти байт начиная с 22-го байта файла.


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

Цитата(XVR @ Mar 14 2017, 10:14) *
А чем вас не устроил в доску стандартный и простой (как та же доска) fscanf ?


Не взлетело. Может как-то данные надо по-другому сформировать. Да я в курсе, что fscanf читает до пробела. Пробовал формировать данные через запятую, но fscanf меня послал
Go to the top of the page
 
+Quote Post
novikovfb
сообщение Mar 14 2017, 12:25
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 225
Регистрация: 29-09-11
Пользователь №: 67 450



Цитата(shtunder @ Mar 14 2017, 16:19) *
Да я в курсе, что fscanf читает до пробела. Пробовал формировать данные через запятую, но fscanf меня послал

лучше через fgets читать строку в буфер, а потом разбирать этот буфер или через sscanf или через strtok разбивать строку на подстроки и обрабатывать каждую подстроку в отдельности (для широких строк может быть эффективнее обработка полей строки циклом)
Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 14 2017, 13:22
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 770
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(shtunder @ Mar 14 2017, 15:19) *
Да я в курсе, что fscanf читает до пробела.

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

fscanf(fp,"%s%d%d%d", name2, &a_code, &b_code, &c_code);
Go to the top of the page
 
+Quote Post
shtunder
сообщение Mar 14 2017, 14:36
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 14-07-14
Пользователь №: 82 243



Цитата(Эдди @ Mar 14 2017, 05:18) *
Смешалось все в кучу...
Зачем fseek? Ничего, что он задает смещение безразлично к пробелам и '\n'?
Если уж пользуете fgets, так считывайте сразу целую строку, сделав буфер достаточного размера, а после считывания при помощи strtod поочередно выкусывайте оттуда числа.
Я при работе с такими вещами делаю проще: mmap файла на строковый буфер, и работаю с ним как с большим текстом, а уж ведро само пусть разбирается, что ему откуда считать — и быстрей получается, и проще.
Т.е. алгоритм такой: 1) mmap файла на буфер, 2) пробегаемся strtod по буферу, контролируя значение endptr, и считываем свои 4096 чисел (ну или меньше, если файл вдруг раньше кончится).


С помощью fseek пытался передвигаться к началу нового числа.
Спасибо за инфу! Про mmap и его быстродействие не знал. Очень познавательно было a14.gif

Цитата(Lagman @ Mar 14 2017, 13:22) *
fscanf может все данные в передаваемой строке положить в переменные вот пример:

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


Это хорошо, когда у есть не очень большое число столбцов. Пример здесь: http://sernam.ru/lect_matlab.php?id=22
Go to the top of the page
 
+Quote Post
admin
сообщение Mar 16 2017, 00:24
Сообщение #9


Администратор форума
******

Группа: Администраторы
Сообщений: 3 094
Регистрация: 11-05-04
Пользователь №: 2



Вроде все починили. Если нет - пишите.
Go to the top of the page
 
+Quote Post

Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th May 2017 - 17:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.04667 секунд с 7
ELECTRONIX ©2004-2016