2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Си странности с fgetpos
Сообщение13.10.2021, 19:54 
Заблокирован


19/02/13

2388
Столкнулся со странным. Простенький кусочек кода:
Используется синтаксис C
do {
    j = fgetc(f);
    printf("%c\n", j);
    //c = fgetpos(f,p);
    printf("J %d\n", j);
} while(j!=-1);


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

Если же раскомментировать строку с $fgetpos$, происходит следующее. Символы всё так же корректно считываются и выводятся в первый раз. После определения позиции значение $j$ почему-то оказывается равным нулю. Далее считывается следующий символ, корректно выводится в первый раз, после определения позиции снова обнуляется и выводится в виде нуля. Разумеется, корректного завершения цикла в этой связи не происходит, программа добегает до конца файла и висит в бесконечном цикле. Обе функции - и чтение символа, и определение позиции - работают без ошибок. Позиция в файле определяется корректно, $fgetpos$ возвращает $0$, что свидетельствует об успехе.

Каким образом получение позиции функцией $fgetpos$ обнуляет значение переменной, успешно считанное перед этим функцией $fgetc$? Чем она принципиально отличается от функции $ftell$, которая в том же коде работает нормально и ничего не ломает?
Хочу разобраться в этом вопросе, подскажите, пожалуйста, где копать.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:11 
Заслуженный участник


18/09/21
1764
А как объявлены j и c? И как объявлена p?
Похоже на memory corruption, видимо когда в p пишется.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:16 
Заблокирован


19/02/13

2388
Всё локально. Это чисто тренировочный код, все собрано в $main()$, там перед циклом всего пара строк с объявлением переменных и открытием файла.

-- 13.10.2021, 20:18 --

$P$ это указатель на $L$, значение $L$ меняется корректно по мере продвижения по файлу, никаких ошибок работы с памятью не возникает.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:18 
Заслуженный участник


18/09/21
1764
Конкретно, напишите как 'p' объявлено. Там нужно ссылку на 'fpos_t' передавать.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:21 
Заблокирован


19/02/13

2388
Используется синтаксис C
fpos_t *p;
p = &l;

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:22 
Заслуженный участник


18/09/21
1764
А 'l' тогда как объявлен?

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:26 
Заблокирован


19/02/13

2388
Просто
Используется синтаксис C
int l;

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:29 
Заслуженный участник


18/09/21
1764
это 'l' должно быть 'fpos_t l'
если нет, а что-то с меньшей длиной, то при записи туда вылезет за пределы и испортит память, например 'j', если оно сразу за 'l' идёт

-- 13.10.2021, 20:31 --

Вобщем правильно так:
Используется синтаксис C
fpos_t p;
do {
j = fgetc(f);
printf("%c\n", j);
c = fgetpos(f,&p);
printf("J %d\n", j);
} while(j!=-1);
 

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:32 
Заслуженный участник


04/05/09
4589
А должно быть
Код:
fpos_t l;

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:32 
Заблокирован


19/02/13

2388
Получилось, спасибо! Поменял тип $l$ и всё заработало как должно. Полезный опыт.

-- 13.10.2021, 20:36 --

Int имеет размер в 4 байта, а fpos_t - 8 байт.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:37 
Заслуженный участник


20/08/14
11867
Россия, Москва
Вообще-то и условие выхода из цикла не там стоит: после конца файла в j будет прочитано -1 (EOF) и тоже обработано как символ, что неправильно.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:41 
Заблокирован


19/02/13

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

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 20:57 
Заслуженный участник


18/09/21
1764
Не понятно, зачем вообще нужен был 'fgetpos'. Нигде его результат не использовался.
А если нужна позиция в файле в виде целого числа, то есть другая функция 'ftell'.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 21:04 
Заблокирован


19/02/13

2388
Хочу обработать данные из одного файла, осваиваю для этого инструменты. Про ftell знаю, она вроде бы проще, но и с fgetpos разобраться тоже интересно.
В целом программирование для меня пока хобби, развлечение.

 Профиль  
                  
 
 Re: Си странности с fgetpos
Сообщение13.10.2021, 21:17 
Заслуженный участник


18/09/21
1764
Vladimir-80 в сообщении #1534864 писал(а):
с fgetpos разобраться тоже интересно
А что с ней разбиратся? Внутренности структуры 'fpos_t' незадокументированы, так что руками в неё лезть не рекомендуется. Единственное, что можно сделать с результатом, это позже вызвать 'fsetpos'.
С 'ftell/fseek' можно хотя бы арифметику применять.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 18 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group