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
1683
А как объявлены 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
1683
Конкретно, напишите как '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
1683
А '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
1683
это '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
4582
А должно быть
Код:
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
11177
Россия, Москва
Вообще-то и условие выхода из цикла не там стоит: после конца файла в 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
1683
Не понятно, зачем вообще нужен был '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
1683
Vladimir-80 в сообщении #1534864 писал(а):
с fgetpos разобраться тоже интересно
А что с ней разбиратся? Внутренности структуры 'fpos_t' незадокументированы, так что руками в неё лезть не рекомендуется. Единственное, что можно сделать с результатом, это позже вызвать 'fsetpos'.
С 'ftell/fseek' можно хотя бы арифметику применять.

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

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



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

Сейчас этот форум просматривают: Missir


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

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