Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/20: Рейтинг темы: голосов - 20, средняя оценка - 4.55
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59

Странное считывание из бинарного файла

12.07.2010, 12:57. Показов 4551. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача такова: считать из бинарного файла числа типа long int (пропустив первые 512 байт) и подставить эти числа в прочку формул.

Вот код на C (под Linux, бинарный файл EU152_1K.SPK)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <math.h>
 
#define LCH 245
#define RCH 255
#define sqr(x) pow(x, 2)
 
struct line {
    double k;
    double b;
};
 
struct line background() /* Фон */ 
{
    int i, c, in;
    long int lb[3], rb[3];
    float avlb, avrb, s;
    struct line co;
    
    in = open("EU152_1K.SPK", O_RDONLY);
    
    for (i = -2; i <= 0; i++) { 
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &c, 4);
        lb[2+i] = c;
    }
    
    for (i = 0; i <= 2; i++) {
        lseek(in, 512 + 4*(i+RCH), SEEK_SET);
        read(in, &c, 4);
        rb[i] = c;
    }
    
    avlb = (lb[0]+lb[1]+lb[2])/3;
    avrb = (rb[0]+rb[1]+rb[2])/3;
    
    s = (avrb+avlb)*(RCH-LCH+1)/2;
    co.k = (avrb-avlb)/(RCH-LCH+1);
    co.b = lb[1] - co.k*(LCH-1);
    close(in);
    
    return co;
}
 
void area() /* Вычисляет площадь и ошибку S */
{
    int i, in;
    long int N, c;
    struct line co;
    float s_err = 0, s = 0;
    
    co = background();
    in = open("EU152_1K.SPK", O_RDONLY);
    for (i = 0; i <= (RCH - LCH); i++) {
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &N, 4);
        c = N;
        s = s + c - ((LCH+i)*co.k + co.b);
        s_err = s_err + c + co.k*(LCH+i)+co.b;
    }
    close(in);
    printf("S = %.2f; S_ERR = %.2f\n", s, sqrt(s_err));
}
 
void p() /* Считаем центр тяжести и ошибку p */
{
    int i, in;
    long int c;
    struct line co;
    float p = 0, s = 0, p_err = 0;
    
    co = background();
    in = open("EU152_1K.SPK", O_RDONLY);
    
    for (i = 0; i <= (RCH - LCH); i++) {
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &c, 4);
        s = s + c - ((LCH+i)*co.k + co.b);
        p = p + (c - ((LCH+i)*co.k + co.b))*(LCH + i);
    }
    
    for (i = 0; i <= (RCH - LCH); i++) {
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &c, 4);
        p_err = p_err + (c + co.k*(LCH+i)+co.b)/sqr(c - co.k*(LCH+i)-co.b) + sqr(227.51)/sqr(38533);
    }
    close(in);
    
    printf("P = %.2f; P_ERR = %.4f\n", p/s, sqrt(p_err));
}
 
void delta() /* Считаем delta */
{
    int i, in;
    long int c;
    struct line co;
    float d = 0, s = 0, p = 0;
    
    co = background();
    in = open("EU152_1K.SPK", O_RDONLY);
    
    for (i = 0; i <= (RCH - LCH); i++) {
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &c, 4);
        s = s + c - ((LCH+i)*co.k + co.b);
        p = p + (c - ((LCH+i)*co.k + co.b))*(LCH + i);
    }
    
    for (i = 0; i <= (RCH - LCH); i++) {
        lseek(in, 512 + 4*(i+LCH), SEEK_SET);
        read(in, &c, 4);
        printf("c = %ld\n", c);
        d = d + (c - ((LCH+i)*co.k + co.b))*sqr(LCH+i - p);
    }
    
    printf("d = %.2f; \n", sqrt(d)/s);
}
 
main()
{
    p();
    area();
    delta();
}
Странное (на мой взгляд) поведение функций заключается в следующем: если отсавить только первые 3 функции background, area, p, то программа функционирует правильно. Но при добавлении функции delta программа неправильно считывает из файла числа (в функции p, area и delta). Помогите кто чем может
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.07.2010, 12:57
Ответы с готовыми решениями:

Запись-считывание строки из бинарного файла
Задача записаить в двоичный файл длину строки и саму строку, а потом считать длину строки и саму строку. #include &lt;stdio.h&gt; ...

Считывание из бинарного файла
СЧИТАТЬ ИЗ БИНАРНОГО ФАЙЛА ВСЕ ВЕЩЕСТВЕННЫЕ ЧИСЛА В МАССИВ И ВЫВЕСТИ ЕГО НА ЭКРАН. #include &lt;iostream&gt; #include &lt;fstream&gt; ...

Считывание бинарного файла
Здравствуйте, Помогите пожалуйста найти проблему, мне нужно вначале записать текст в бинарный файл а затем считать его, записывает...

34
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
13.07.2010, 12:06
Студворк — интернет-сервис помощи студентам
C
1
lseek(in, 512 + 4*(i+LCH), SEEK_SET);
а зачем делать это каждый раз
можно один раз переместиться на 512 байт, а потом подряд прочитать числа
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
13.07.2010, 13:13  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
C
1
lseek(in, 512 + 4*(i+LCH), SEEK_SET);
а зачем делать это каждый раз
можно один раз переместиться на 512 байт, а потом подряд прочитать числа
Функция read перемещает указатель в конец чтения? Если да, то едйствительно lseek можно и не использовать, но ведь и хуже он делать тоже не должен?
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
14.07.2010, 19:07  [ТС]
Ну что так никто и не поможет?
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
15.07.2010, 02:32
Цитата Сообщение от dasalam
то едйствительно lseek можно и не использовать, но ведь и хуже он делать тоже не должен?
у тебя по всему коду эти lseek'и, во-первых - это системный вызов (он требует больше ресурсов операционной системы, ладно по ресурсам, он не переносим между системами), а во-вторых он должен быть один в программе
из-за этого у тебя программа в два раза длинее, чем, по идее, должна быть

Цитата Сообщение от dasalam
Ну что так никто и не поможет?
с дельтой ?

Цитата Сообщение от dasalam
Задача такова: считать из бинарного файла числа типа long int (пропустив первые 512 байт) и подставить эти числа в прочку формул.
открываешь файл, применяешь один раз fseek(), считываешь с помощью fread() числа типа long int, закрываешь файл, работаешь с массивом

а то, что у тебя написано - несколько раз открывается файл, несколько раз каждый раз переводится указатель в файле, несколько раз считываются числа

а потом, когда проблемы с дельта, пишешь, что такое дельта
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
15.07.2010, 11:47
Выложи входной бинарный файл прямо в форум
Выкини код рассчетов - сначала разберись с чтением из файла
Напиши простую программу, которая читает и печатает
Выложи в форум
Тогда может кто и попробует ее
А так все только гадают в чем косяк

И кстати программа твоя должна быть портабельной - то есть работать на других компах или тебе надо ее только на одном твоем компе запустить ?

Добавлено через 1 минуту
Самое главное забыл - после open(), lseek(), read() надо проверять код возврата
Можешь сильно не думать - в случае ошибки сразу выводить что ошибка и делать exit()
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
15.07.2010, 14:05  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
у тебя по всему коду эти lseek'и, во-первых - это системный вызов (он требует больше ресурсов операционной системы, ладно по ресурсам, он не переносим между системами), а во-вторых он должен быть один в программе
из-за этого у тебя программа в два раза длинее, чем, по идее, должна быть


с дельтой ?


открываешь файл, применяешь один раз fseek(), считываешь с помощью fread() числа типа long int, закрываешь файл, работаешь с массивом

а то, что у тебя написано - несколько раз открывается файл, несколько раз каждый раз переводится указатель в файле, несколько раз считываются числа

а потом, когда проблемы с дельта, пишешь, что такое дельта
Я так и сделал. Считал числа в массив и работаю с этим массивом. Просто интересно, что в этой программе не так.

2odip: код рассчетов тут скорее всего ни причем, потому что как я уже показывал программа не правильно считывает числа из файла. код возврата посмотрю, спасибо.
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
16.07.2010, 04:18
Цитата Сообщение от dasalam
Я так и сделал. Считал числа в массив и работаю с этим массивом.
сделай программу printf("%lu %lu" "\n", sizeof(int), sizeof(long));
как я и говорил, читаешь по четыре, а оно не равно четыре, так как c = 1234987238972341234 значит, что у тебя sizeof(long int) равно восемь
1
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
16.07.2010, 12:59  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
сделай программу printf("%lu %lu" "\n", sizeof(int), sizeof(long));
как я и говорил, читаешь по четыре, а оно не равно четыре, так как c = 1234987238972341234 значит, что у тебя sizeof(long int) равно восемь
Действительно 8. Но почему то до добавления последней функции все считывалось нормально. Да если в приведенном коде все long int заменить на int, то все ок.
Числа, кстати, я считывал из массива long int и все нормально.
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
17.07.2010, 03:06
Цитата Сообщение от dasalam
Числа, кстати, я считывал из массива long int и все нормально.
как оно могло считываться нормально, если считываешь по четыре байта, а long int равно восемь ?

C
1
read(in, &c, 4);
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
17.07.2010, 12:56  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
как оно могло считываться нормально, если считываешь по четыре байта, а long int равно восемь ?

C
1
read(in, &c, 4);
А если например вызываешь printf так:
C
1
printf("%d\n", c);
Хотя было
C
1
2
long int c;
read(in, &c, 4);
То как printf преобразует long int в int? Если c не превышает max допустимого для int то все должно быть нормально?
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
19.07.2010, 02:40
если у тебя числа в файле long int, то они там все по восемь байт
а ты читаешь по четыре (по половине числа, короче) и результаты у тебя не могут быть правильными

я там в начале писал, как нужно считывать
C
1
read(in, &c, sizeof c);
и c должно быть long int

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

Цитата Сообщение от dasalam
А если например вызываешь printf так:
а какая разница, если ты число из файла неправильно прочитал, надо было восемь, а ты четыре (printf будет выводить всё, что сможет вывести, если что-то будет вылезать за край, она будет выводить до края)

Добавлено через 3 минуты
printf
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    long long n;
    
    n = 100000000000;
    
    printf("%lld" "\n", n);
    
    printf("%d" "\n", n);
    
    return EXIT_SUCCESS;
}
Code
1
2
3
4
[guest@station src]$ ./test
100000000000
1215752192
[guest@station src]$
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
20.07.2010, 00:18  [ТС]
Я наверное не правильно выразился. Числа нужно читать по 4 байта
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.07.2010, 05:05
проверь просто чтение четырёх байт в одну переменную типа long
чтобы её можно было прочитать и вывести
0
10 / 10 / 0
Регистрация: 14.12.2008
Сообщений: 59
20.07.2010, 13:23  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
проверь просто чтение четырёх байт в одну переменную типа long
чтобы её можно было прочитать и вывести
В программе так и есть
C
1
2
3
long int c;
...
read(in, &c, 4);
Если выводить с так printf("%d", c); то все нормально, а если так printf("%ld", c); то получаются неправильно выведенные числа.
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
21.07.2010, 02:30
sizeof(short) ещё проверь, может он там четыре байта
это если у тебя задание не прочитать long int'ы, а прочитать числа по четыре

сделай так
C
1
printf("%ld", (long) c)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.07.2010, 02:30

Считывание бинарного файла
Здравствуйте! Изначально нужно было прочитать почисленно текстовый файл и забить его в массив. Но т.к. это не получилось, решил прочитать...

Считывание с бинарного файла
Реализовать программу, которая считывает из исходного текстового файла записи определенной структуры в динамический массив. Записи в...

Считывание и запись бинарного файла
файл считывается, записывается в массив. Затем создается новый файл, в него записываются данные из массива. Содержимое исходного...

Считывание бинарного файла в ASP
Добрый день. Есть задача: считать бинарный файл и как есть запихать его браузеру (через response.binaryWrite). По MSDN...

Считывание данных из бинарного файла
Доброго времени суток. Моя проблема уже была озвучена в теме. Вот листинг функции которая должна считывать данные из бинарного...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru