|
|
  |
Чтение из файла данных на си, Необходимо считать числа из файла |
|
|
|
Mar 14 2017, 02:37
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 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 элемента
|
|
|
|
|
Mar 14 2017, 03:32
|
Местный
  
Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682

|
Цитата(shtunder @ Mar 14 2017, 04:37)  Т.е. необходимо считывать первую строку, потом вторую и т.д. Если важно, то в каждой строке 8192 элемента У Вас не изменяется значение индекса i. Программа должна зациклиться на постоянном чтении 19-ти байт начиная с 22-го байта файла.
|
|
|
|
|
Mar 14 2017, 05:18
|
Знающий
   
Группа: Участник
Сообщений: 825
Регистрация: 16-04-15
Из: КЧР, Нижний Архыз
Пользователь №: 86 250

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

Группа: Участник
Сообщений: 24
Регистрация: 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 меня послал
|
|
|
|
|
Mar 14 2017, 13:22
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 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);
|
|
|
|
|
Mar 14 2017, 14:36
|
Участник

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

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