fgetc без увеличения указателя ИЛИ уменьшения объекта fpos_t (C)

Так и не нашел ответа на этот вопрос.

Есть ли:

  1. Функция, похожая на fgetc, которая извлекает символ по указателю без увеличения указателя?

  2. ИЛИ способ уменьшить объект fpos_t без уменьшения указателя под ним.(В основном интересует этот ответ)

Для С.


person theamycode    schedule 08.10.2014    source источник
comment
Что-то вроде этого? stackoverflow.com/a/2082772/535275   -  person Scott Hunter    schedule 08.10.2014
comment
О каком fpos_t объекте вы говорите, что за указатель под ним и чем они отличаются?   -  person Keith Thompson    schedule 08.10.2014


Ответы (1)


У вас есть три варианта:

1) используйте ftell/fseek

Пример:

  FILE * pFile;
  char c1, c2;
  long offset;
  pFile = fopen ( "example.txt" , "r" );
  offset = ftell(pFile);
  c1 = fgetc(pFile);
  fseek ( pFile , offset , SEEK_SET );
  c2 = fgetc(pFile);
  /* result: c1 == c2 */

(Примечание: для бинарного потока вы также можете попробовать использовать fseek(pFile, -1, SEEK_CUR), но для текстового режима, как было отмечено, получение одного символа может сдвинуть указатель более чем на одну позицию).

2) используйте fgetpos/fsetpos

Пример:

  FILE * pFile;
  fpos_t position;
  char c1, c2; 
  pFile = fopen ("example.txt","r");
  fgetpos (pFile, &position);
  c1 = fgetc(pFile);
  fsetpos (pFile, &position);
  c2 = fgetc(pFile);
  /* result: c1 == c2 */

3) используйте ungetc

  FILE * pFile;
  char c1, c2;
  c1 = fgetc(pFile);
  ungetc(c1, pFile);
  c2 = fgetc(pFile);
  /* result: c1 == c2 */

Какой из этих методов будет более эффективным, зависит от платформы и реализации. Например. может случиться так, что под капотом ungetc, например, перечитает текущий фрагмент до текущей точки. Или может быть, что он просто перемещает указатель в буфере памяти.

person Ashalynd    schedule 08.10.2014
comment
В первом примере вы хотели бы использовать ftell для определения текущей позиции перед fgetc, а затем вернуть ее обратно в fseek. Чтение одного символа из текстового потока может опережать его более чем на 1 байт (например, чтение новой строки из текстового файла Windows возвращает '\n', но потребляет '\r' и '\n'). Конечно, это работает, только если файл доступен для поиска; вы не можете перемотать stdin, например. - person Keith Thompson; 08.10.2014
comment
Обратите внимание, что ungetc() имеет некоторые интересные свойства, связанные с функциями позиционирования файлов. Внимательно прочитайте его спецификацию. - person Jonathan Leffler; 08.10.2014