Что такое код ftell


Что такое код ftell

int fseek(FILE * stream , long offset , int whence );
long ftell(FILE * stream );
void rewind(FILE * stream );
int fgetpos(FILE * stream , fpos_t * pos );
int fsetpos(FILE * stream , fpos_t * pos );

ОПИСАНИЕ

Функция ftell получает текущее значение позиции в файле для потока, на который указывает stream .

Функция rewind устанавливает позицию в файле для потока, на который указывает stream , равную началу файла. Эта функция эквивалентна вызову

(void)fseek(stream, 0L, SEEK_SET),

хотя в этом случае «очищается» также индикатор ошибок (см. clearerr (3)).

Функции fgetpos и fsetpos равны по значению вызовам ftell и fseek (при этом значение положения (whence) установлено равным SEEK_SET ); они сохраняют (или устанавливают) текущее значение смещения в файле в объектах, определяемых pos , или берут эти значения из данных объектов. В некоторых не-UNIX системах объект fpos_t может быть сложным объектом, а данные функции могут быть единственным способом быстро менять позицию в текстовом потоке.

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ


НАЙДЕННЫЕ ОШИБКИ

Фукнции fgetpos , fseek , fsetpos и ftell при ошибках устанавливают значение глобальной переменной errno равным значению, определенному в функциях fflush (3), fstat (2), lseek (2) и malloc (3).

Функция ftell

Функция ftell() возвращает текущее значение указателя позиции файла для заданного потока. В случае двоичных потоков это значение равно количеству байтов, которые отделяют указатель от начала файла. Для текстовых потоков возвращаемое значение может не иметь определенной интерпретации за исключением случая, когда оно является аргументом функции fseek() . Все дело в возможных преобразованиях символов, когда, например, комбинация кодов возврата каретки (ASCII 13) и конца строки (ASCII 10) заменяются разделителем строк, что влияет на размер файла.

При возникновении ошибки функция ftell() возвращает значение -1.

Пример

Данный фрагмент программы считывает текущее значение указателя позиции файла, связанного с потоком, который задается параметром fp .

Функция ftell

Функция ftell() возвращает текущее значение указателя позиции файла для заданного потока. В случае двоичных потоков это значение равно количеству байтов, которые отделяют указатель от начала файла. Для текстовых потоков возвращаемое значение может не иметь определенной интерпретации за исключением случая, когда оно является аргументом функции fseek() . Все дело в возможных преобразованиях символов, когда, например, комбинация кодов возврата каретки (ASCII 13) и конца строки (ASCII 10) заменяются разделителем строк, что влияет на размер файла.

При возникновении ошибки функция ftell() возвращает значение -1.

Пример

Данный фрагмент программы считывает текущее значение указателя позиции файла, связанного с потоком, который задается параметром fp .

Описание функций языка Си

All | _ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

ftell – опрос текущей позиции в потоке данных.

#include
long int ftell (FILE *stream);

stream – указатель на управляющую таблицу потока данных.

Позиция в потоке данных, если работа функции завершена удачно.
Если при определении позиции произошла ошибка, то возвращается -1.

Функция ftell определяет текущую позицию в потоке данных, на который указывает аргумент stream.

Для двоичных потоков данных позиция соответствует количеству байтов от начала файла. Для текстовых потоков данных получаемое число может не совпадать с количеством байтов от начала файла и должно использоваться только функцией fseek() для установки потока данных в ту же позицию.

В примере открывается файл для чтения, содержащий строку «тест чтения». Определяется текущая позиция в файле сразу после его открытия, а затем после чтения одного символа. Результаты определения позиции выводятся на экран.

Вывод на консоль:

Открытие файла: выполнено
Определение позиции: 0
Чтение из файла символа: т
Определение позиции: 1
Закрытие файла: выполнено

Пытаясь понять, возвращаемое значение функции ftell

Вывод

Мой smaple.txt файл имеет только один символ , и это д. Почему это показывает 3 здесь? Кроме того, когда я имею файл пустой, то ftell () возвращает 1, что это такое?
Работа на Ubuntu 12.04

Ваши fseek(file, 1, SEEK_END) места позиция один символ за конец файла. Это объясняет , почему вы наблюдаете , count как один для пустого файла. Я предполагаю , что файл, который содержит только водн, также содержит возврат каретки , состоящий из собственно два символа. По характеру позади конца 3, что вы наблюдали.

Вы можете использовать fseek() неправильно определить размер файла с помощью ftell() .

INT FSEEK (FILE * поток, длинные смещения, Int откуда);

[. ] Новое положение, измеренное в байтах, получается путем добавления смещения байтов в позиции , заданной откуда .

помещает указатель файла 1 байт после конца файла.

Чтобы исправить это сделать:

Вы извратили функции ftell & FSEEK. Меньше кофе больше отдыха: р

ftell страница руководства

Функция ftell () получает текущее значение индикатора позиции файла для потока, на который указывает поток.

FSEEK страница руководства

INT FSEEK (FILE * поток, длинные смещения, Int откуда);

Функция FSEEK () устанавливает индикатор позиции файла для потока, на который указывает поток. Новое положение, измеренное в байтах, получаются путем добавления смещения байт в положении спектрометре маньяков с помощью откуда. Если откуда установлен в SEEK_SET, SEEK_CUR или SEEK_END, смещение относительно начала файла, текущего указателя положения, или с истекшим файла, соответственно. Успешный вызов функции FSEEK () очищает индикатор конца файла для потока и отменяет все эффекты ungetc (3) функции на тот же поток.

Что такое код ftell

Самая актуальная документация по Visual Studio 2020: Документация по Visual Studio 2020.

Получает текущее положение указателя файла.

Параметры

stream
Целевая структура FILE .

Функции ftell и _ftelli64 возвращают текущее положение в файле. Значение, возвращаемое функциями ftell и _ftelli64 , может не отражать физическое смещение в байтах для потоков, открытых в текстовом режиме, поскольку в текстовом режиме производится преобразование символов возврата каретки и перевода строки (CR-LF). Используйте ftell с fseek или _ftelli64 с _fseeki64 для возврата расположения файлов правильно. В случае ошибки ftell и _ftelli64 вызывают обработчик недопустимого параметра, как описано в проверки параметров. Если выполнение может быть продолжено, эти функции возвращают –1L и устанавливают параметр errno в значение одной из двух констант, определенных в файле ERRNO.H. Константа EBADF означает, что аргумент stream не является допустимым значением указателя файла или не ссылается на открытый файл. Константа EINVAL означает, что функции передан недопустимый аргумент stream . Если устройство неспособно выполнять поиск (например, терминалы и принтеры) или если stream не ссылается на открытый файл, возвращаемое значение не определено.

В разделе _doserrno, errno, _sys_errlist и _sys_nerr Дополнительные сведения об этих и других кодах возврата.

ftell И _ftelli64 функции получить текущее положение указателя файла (если таковые имеются), связанного с stream . Позиция представляется как смещение относительно начала потока.

Обратите внимание, что когда файл открыт для добавления данных, текущее положение в файле определяется последней операцией ввода-вывода, а не тем, где должна быть произведена следующая запись. Например, если файл открыт для добавления и последней операцией было чтение, положением в файле является место, где должна начинаться следующая операция чтения, а не следующая операция записи. (Если файл открыт для добавления, положение в файле перемещается в конец файла перед любой операцией записи.) Если в открытом для добавления файле еще не производилась ни одна операция ввода-вывода, то положением в файле является начало файла.

Илон Маск рекомендует:  Что такое код isset

В текстовом режиме при вводе CTRL+Z интерпретируется как символ конца файла. В файлах, открытых для чтения/записи, функция fopen и все связанные с ней подпрограммы проверяют наличие символа CTRL+Z в конце файла и удаляют его, если это возможно. Это связано с тем, что использование сочетания функций ftell и fseek или _ftelli64 и _fseeki64 для перемещения в файле, который заканчивается символом CTRL+Z, может вызвать неправильное поведение функции ftell или _ftelli64 рядом с концом файла.

Во время выполнения функция блокирует вызывающий поток, поэтому она потокобезопасна. Сведения о неблокирующей версии см. в описании функции _ftell_nolock .

Функция Обязательный заголовок Необязательные заголовки
ftell
_ftelli64

Дополнительные сведения о совместимости см. в разделе Совместимость во введении.

Мобильные операторы и Интернет в Черногории

Мобильные операторы и Интернет в Черногории

Сотовая связь в Черногории

В Черногории на сегодняшний день существуют три оператора, которые предоставляют во многом схожие пакеты услуг. Это Telenor (069), T-Mobile (067) и M: Tel (068). Из них только последняя компания является местной, что не мешает ей успешно конкурировать с первыми двумя. Сотовая связь в Черногории доступна практически на всей ее территории (более 90%), исключение составляют удаленные горные районы и каньоны рек.

Приобретение и регистрация сим-карты

Приобрести местную сим-карту можно где угодно – как в официальных представительствах, так и в большинстве киосков и газетных ларьков. При этом вам в любом случае необходимо зарегистрировать ее в ближайшем отделении компании. Конечно, вы можете сделать это в точке покупки, однако это не гарантирует попадание информации в базу данных. Да, в офисах вам придется выстоять очередь (от 5 до 15 минут), но зато там вы можете сразу подключить нужный вам тарифный план и настроить телефон таким образом, чтобы не пришлось платить за воздух. Сотрудник компании по вашей просьбе введет нужные комбинации цифр и отключит передачу данных, которая съедает львиную долю интернет-трафика.

Важно! Незарегистрированные номера вскоре после активации будут отключены оператором.

Но даже если вы не стали обращаться к официальному представителю, и ваши регистрационные данные были успешно внесены в базу, стоит уделить особое внимание услугам, к которым вы подключены. Обычно в газетных киосках продаются так называемые «туристические» тарифы с крайне невыгодными условиями.

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

Черногорские операторы

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

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

PRE-PAID

Если мы говорим о тарифах pre-paid, то есть предоплате (туристам доступен только этот формат), то на сегодняшний день здесь наблюдается следующая ситуация.

T-Mobile предлагает 4 основных пакета: MI, SVI, SURF и STOTKA.

Каждый из них обойдется вам в 2,90 евро, при этом MI подразумевает 500 бесплатных минут телефонных разговоров внутри сети, 500 смс (также внутри сети) и 1 Гб интернета. SVI предлагает 100 бесплатных минут и столько же смс по всем местным направлениям плюс 500 Мб интернета. SURF обеспечит вас 1,5 Гб интернета и еще 2 Гб трафика для пользования социальными сетями Facebook, Twitter и FB Messenger. STOTKA предлагает кредит в 100 евро за пользование всеми доступными услугами. Все настройки доступны при наборе *111# — эта комбинация выведет вас в соответствующее меню. И помните о том, что подключение опций и выбор соответствующего тарифа бесплатны только в первый раз – в дальнейшем придется платить.

Telenor предлагает 2 основных предоплаченных пакета: Telenor Besplatno и Start.

Telenor Prepaid 2020 подразумевает бесплатное подключение тарифа Telenor Besplatno, который предлагает 100 бесплатных минут по всем черногорским направлениям, а также 1000 минут в сети и 1 Гб интернета – все эти услуги доступны в течение 7 дней после активации. После этого клиент имеет возможность за 3 евро подключить тариф Start, который будет включать все преимущества Telenor Besplatno, а также выгодные условия по звонкам по Черногории и Сербии. Все настройки можно осуществить в меню сервиса, набрав *123#. Правда, тарифный план можно менять не чаще одного раза в течение календарного месяца.

M: Tel предлагает 3 основных пакета pre-paid: Hello, M:Go и Turist.

Hello за 5 евро подразумевает 4 Гб интернета, причем можно заказать дополнительные 5 Гб за 4,9 евро. В остальном цены на звонки практически не отличаются от остальных операторов: 0,22 евро по всем черногорским направлениям, 0,85 евро на все международные номера. Плюсом тарифа является услуга «Друзья и семья», в которой цена за минуту разговора составляет всего 9 центов.

M:Go за все те же 5 евро предлагает 100 бесплатных минут и 100 смс вместе с 10 Гб интернета, которые вы должны использовать за 7 дней после активации. Также в течение 6 месяцев у вас будет бесплатный доступ к социальным сетям Facebook, Viber, Instagram, Twitter, What’s App, Wikipedia и Mondo GO. При этом стоимость звонком в дальнейшем ниже, чем в предыдущем пакете: 0,149 евро на все черногорские номера, хотя международные разговоры обойдутся вам в привычные 0,85 евро/мин.

Turist (неизменные 5 евро) обеспечит вам 10 Гб интернета и среднестатистические цены на звонки и смс: 0,22 евро/мин за звонок на любой черногорский номер, 0,059 евро за смс на любого местного оператора. Плюсом услуги является то, что при каждой новой оплате вы получаете свои первоначальные 10 Гб интернета.

Что касается настроек M: Tel, то лучше их осуществлять непосредственно в официальных пунктах, поскольку компания активно использует систему смс, в которой легко запутаться. Например, чтобы переключиться с предоплаченного Hello на post-paid Send Hello, вам будет необходимо отправить сообщение с текстом «pp send» на номер 100. Чтобы вернуться к предыдущему тарифу, нужно будет проделать ту же операцию, но с текстом «pp hello», при этом смена тарифа может быть осуществлена не чаще одного раза в календарным месяц. В общем, проще зайти в офис и все настроить с помощью сотрудника компании. Или очень внимательно изучить информацию на официальном сайте оператора.

POST-PAID

Post-paid в Черногории доступны только местным гражданам или лицам, постоянно здесь проживающим (о чем должны иметься подтверждающие документы). Поэтому если вы приехали на пару недель, то эта информация вряд ли заинтересует вас.

Telenor предлагает своим клиентам 4 пакета post-paid, минимальный из которых стоит 12,9 евро, а максимальный – 35,9 евро. Интернет – от 1 до 3 Гб, телефония – от 125 до 600 минут по всем местным направлениям (звонки внутри сети не ограничены) и количество смс от 125 до 3000.


T-Mobile разбил свою post-paid линейку на 5 секторов – от 9,90 евро до 55,90 евро. Количество бесплатных минут увеличивается от 100 до 1200, при этом разговоры внутри сети не ограничены. Количество смс варьируется от 100 до бесконечности, а интернет-трафик – от 1 Гб до безлимитного.

M: Tel предлагает 4 тарифа: Urban S (10,90 евро), Urban M (15,90 евро), Urban L (25,90 евро), Urban XL (29,90 евро). Соответственно цене растет и количество предоставляемых минут, смс и гигабайт, включая безлимитный доступ к социальным сетям и различным мобильным приложениям.

ИНТЕРНЕТ

Для пользования мессенджерами вам достаточно будет мобильного интернета – местная связь 3G имеет очень хорошее покрытие и доступна практически везде, не считая отдаленных районов и иногда встречающихся «ям». Все настройки могут прописать сотрудники компании, в которую вы обратитесь, но если такой возможности нет, то вот необходимые данные:

Telenor. Имя: Telenor MNE Internet. APN: internet. Имя пользователя: gprs. Пароль: gprs. Proxy IP:192.168.246.005. Proxy port: 8080 или 9201.

T-Mobile. Имя: GPRS. APN: tmcg-wnw. Имя пользователя: 38267. Пароль: 38267. Proxy IP:10.0.5.19. Proxy port: 8080.

M: Tel. Имя: mtelinternet. APN: mtelinternet. Имя пользователя: internet. Пароль: 068. Proxy IP и Proxy port: по умолчанию.

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

Что касается тарифов на pre-paid интернет-пакеты, то они в Черногории следующие:

  • Telenor – от 9,95 евро (4 Гб) до 49,95 евро (15 Гб + usb-модем). Услуга действует от 15 дней (самый бюджетный пакет) до 30 дней с момента активации.
  • T-Mobile – предлагает только два пакета для туристов: за 9,90 и 19,90 евро соответственно. Продолжительной обеих услуг – 10 дней; разница состоит лишь в том, что во втором случае к сим-карте прилагается usb-модем. В дальнейшем вы можете пополнять счет многократно по следующей схеме: 1 день (1 Гб) – 1 евро, 5 дней (5 Гб) – 7 евро, 10 дней (неограниченный интернет) – 10 евро, 30 дней (20 Гб) – 20 евро.
  • M: Tel – в настоящий момент доступен единственный пакет Hello Net, который включает 4 Гб за 5 евро при первом пополнении и 4,9 евро за каждые последующие 5 Гб.
РЕЗЮМЕ

Как уже говорилось выше, местные тарифы не отличаются большим разбросом цен: разговоры внутри страны обойдутся вам в среднем в 0,16-0,22 евро за минуту, sms – от 4 до 6 центов. При этом есть специальные предложения, в которых одна из опций выглядит особенно заманчивой. Вам остается только выбрать, что именно для вас важнее – дешевые смс-ки или определенное количество бесплатных звонков.

Внимание! Если вы уезжаете из Черногории, но планируете вернуться в следующем году и не хотите потерять существующий номер, нужно будет обеспечить хотя бы минимальное движение по вашему счету. Как правило, действие неактивной сим-карты прекращается спустя 330 дней после последнего платежа.

Что такое код ftell

(PHP 3, PHP 4, PHP 5)

ftell — Сообщает текущее смещение чтения/записи файла

Описание int ftell ( resource handle )

Возвращает смещение файлового указателя, ассоциируемого с handle .

При возникновении ошибки, возвращает FALSE .

Пример 1. Пример использования функции ftell()

// открываем файл и читаем немного данных
$fp = fopen ( «/etc/passwd» , «r» );
$data = fgets ( $fp , 12 );

// где же мы ?
echo ftell ( $fp ); // 11

Есть случаи, когда FSEEK/ftell может дать неправильный размер файла?

В C или C++, следующий может быть использован, чтобы вернуть размер файла:

Существует ли какое-среда разработки, компиляторы, или операционка, которая может вернуть неправильный размер файла из этого кода, на основе дополнения или другой информации, которая является конкретной ситуацией? Были ли изменения в C или C++ спецификации около 1999, что привело бы к этому коду больше не работает в некоторых случаях?

Для этого вопроса, пожалуйста, предположим, я добавляю поддержку больших файлов путем компиляции с флагами -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 . Благодарю.

4 ответа

Возможно, для Вашего проекта будут необходимы бесплатные векторные карты. На нашем сайте представлены карты для всех стран.

Он не будет работать на unseekable файлы, такие как /proc/cpuinfo или же /dev/stdin или же /dev/tty , или файлы трубы получили с popen

И это не будет работать, если этот файл записывается другим процессом одновременно.

С помощью Posix стат функция, вероятно, более эффективным и более надежным. Конечно, эта функция может быть недоступна в системах, отличных Posix.

fseek а также ftell функции, как определено стандартом ISO C языка.

Далее от последний открытый проект стандарта 2011 C, но в 1990, 1999 и 2011 стандартов ISO C очень похожи в этой области, если не идентичны.

Функция ftell получает текущее значение позиции в файле индикатор для потока, на который указывает поток. Для двоичного потока, значение количество символов от начала файла. Для текстового потока, его индикатор позиции файла содержит неопределенный Информация, полезная в FSEEK функции для возвращения файла Индикатор положения потока в его положение в момент проведения ftell звонок; разница между двумя такими возвращаемые значения не обязательно значимая мера количества записанных символов или читать.

FSEEK функция устанавливает индикатор позиции файла для потока указывает поток. Если ошибка чтения или записи возникает ошибка индикатор для потока устанавливается и FSEEK терпит неудачу.

Для бинарного потока, новое положение, измеренный в символах от начало файла, получается путем добавления смещения к положение задается откуда. Указанная позиция является начало файла, если откуда это SEEK_SET, текущее значение индикатор позиции файла, если SEEK_CUR или отслуживший файл, если SEEK_END. Двоичный поток не должен осмысленно поддерживать FSEEK вызовов с откуда значением SEEK_END.

Для текстового потока, либо смещение должно быть нулевым, или смещение должен быть значением, возвращенным более ранним успешного вызова Функция ftell на поток, связанный с тем же файлом и откуда должны быть SEEK_SET.

Нарушив любой из «должен» пунктов делает поведение вашей программы не определено.

Так что, если файл был открыт в двоичном режиме, ftell дает количество символов от начала файла — но fseek относительно конца файла ( SEEK_END ) Не обязательно является значимым. Это приспосабливает системы, в которых хранятся двоичные файлы целыми блоками и не отслеживают, сколько было написано в последний блок.

Если файл был открыт в текстовом режиме, вы можете обратиться в начало или конец файла со смещением 0, или вы можете обратиться к позиции, заданной в предыдущем вызове ftell ; fseek с любыми другими аргументами имеет неопределенное поведение. Это приспосабливает системы, где количество символов, считанных из текстового файла не обязательно соответствует количеству байт в файле. Например, на Windows, чтение CR-LF (пара «\r\n» ) Читает только один символ, но продвигает 2 байта в файле.

На практике, на Unix-подобные системы текст и бинарные режимы ведут себя так же, как и методы FSEEK/ftell будут работать. Я подозреваю, что это будет работать на Windows, (я думаю, что ftell даст байтовое смещение, которое не может быть такой же, как, сколько раз вы могли бы назвать getchar() в текстовом режиме).

Следует также отметить, что ftell() возвращает результат типа long . В системах, где long составляет 32 бит, этот метод не может работать для файлов, которые 2 Гб или больше.

Вы могли бы быть лучше использовать какой-либо метод конкретной системы, чтобы получить размер файла. Поскольку FSEEK/ftell метод конкретной системы в любом случае, такие, как stat() на Unix-подобных системах.

С другой стороны, fseek а также ftell скорее всего, работать, как вы ожидаете от большинства систем вы, вероятно, столкнуться. Я уверен, что есть системы, где она не будет работать; извините, но у меня нет конкретики.

При работе на Linux и Windows, это достаточно хорошо, и вы не связаны с большими файлами, то FSEEK/ftell метод, вероятно, хорошо. В противном случае, вы должны рассмотреть возможность использования метода конкретной системы для определения размера файла.

И имейте в виду, что все, что говорит вам размер файла может только сказать вам, его размер в тот момент. размер файла может измениться, прежде чем получить доступ к нему.

1) Поверхностно, ваш код выглядит «OK» — Я не вижу никаких проблем с этим.

2) Нет — нет никакого «C или спецификации C++», который будет влиять на FSEEK. Существует спецификация Posix:

3) Если вы хотите «размер файла», мой первый выбор будет вероятно «стат()». Вот спецификация Posix:

4) Если что-то «происходит не так» с методом, то моя первая догадка была бы «поддержка больших файлов».

Например, во многих ОС было параллельно «FSEEK()» и «fseek64()» API.

‘«Надеюсь, что помогает .. PSM

POSIX определяет возвращаемое значение из FSEEK как «измеряется в байтах от начала файла». Твой at_beg всегда будет равна нулю (при условии, что это недавно открытый файл).

Таким образом, при условии, что:

  1. файл доступный для поиска
  2. нет параллельности вопросов, которые будут обеспокоены
  3. размер файла представим в типе данных, используемом в варианте FSEEK/ftell вы выбираете

то ваш код должен работать на любой POSIX-совместимой системе.

c — Используйте ftell для поиска размера файла

Если ftell (f) сообщает нам текущую позицию файла, размер здесь должен быть смещением от конца файла до начала. Почему размер не равен (f) +1? Должна ли ftell (f) указывать только позицию конца файла?

    3 2
  • 26 май 2020 2020-05-26 13:55:54
  • OptatootatpO

2 ответа

Я не уверен, почему fseek() / ftell() используется как общий способ получить размер файла. Он работает только потому, что реализация определяет его работу. POSIX делает для одного. Windows также используется для двоичных потоков, но не для текстовых потоков.

Неправильно не добавлять оговорку или предупреждение: «Вот как вы получаете количество байтов в файле». Потому что, когда программист сначала попадает в систему, которая не определяет fseek() / ftell() как смещения байта, у них будут проблемы. Я видел это.

«Но мне сказали, что так можно всегда это делать».

«Ну, нет. Тот, кто тебя учил, ошибался».

Потому что невозможно использовать fseek() / ftell() чтобы получить размер файла в строго соответствующем C-коде.

Для двоичного потока, 7.21.9.2 Функция fseek , пункт 3 стандарта C:

Для двоичного потока новая позиция, измеренная в символах с начала файла, получается путем добавления offset к позиции, заданной по whence . Указанное положение является начало файла, если whence это SEEK_SET , текущее значение индикатора позиции файла, если SEEK_CUR, или с истекшим файла, если SEEK_END . Бинарный поток не нуждается в значимой поддержке вызовов fseek с значением whence SEEK_END .

В сноске 268 конкретно говорится:

Установка индикатора положения файла в конец файла, как и в fseek(file, 0, SEEK_END) , имеет неопределенное поведение для двоичного потока (из-за возможных конечных нулевых символов) или для любого потока с зависящей от состояния кодировкой, которая не конечно, заканчиваются в начальном состоянии сдвига.

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

И для текстового потока, 7.21.9.4. Функция ftell , пункт 2, гласит:

Функция ftell получает текущее значение индикатора положения файла для потока, на который указывает stream . Для двоичного потока значение — это количество символов в начале файла. Для текстового потока индикатор положения файла содержит неопределенную информацию, которую можно использовать функцией fseek для возврата указателя позиции файла для потока в его положение во время вызова ftell ; разница между двумя такими возвращаемыми значениями необязательно является значимой мерой количества написанных или прочитанных символов.

Поэтому вы не можете использовать ftell() в текстовом потоке, чтобы получить количество байтов.

Единственный строго-совместимый подход, который я знаю, чтобы получить количество байтов в файле, — это читать их один за другим с помощью fgetc() и подсчитывать их.

  • 26 май 2020 2020-05-26 13:55:55
  • Andrew Henle

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

Это гипотетический файл. Он содержит четыре символа: a , b , c и d . Каждый персонаж получает маленькую коробку для себя, которую мы называем «байтом». (Этот файл является ASCII.) Пятое поле было вычеркнуто, потому что оно еще не является частью файла, но если вы добавили пятый символ в файл, он возникнет.

Допустимые позиции файла в этом файле: 0, 1, 2, 3 и 4. Их пять, а не четыре; они соответствуют вертикальным линиям до, после и между ящиками. Когда вы открываете файл (если вы не используете «a» ), вы начинаете в позиции 0, строка перед первым байтом в файле. Когда вы пытаетесь дойти до конца, вы попадаете в позицию 4, линию после последнего байта в файле. Поскольку мы начинаем отсчет с нуля, это также количество байтов в файле. (Это одна из нескольких причин, почему мы начинаем отсчет с нуля, а не один.)

Я обязан предупредить вас, что есть несколько причин, почему

может не дать вам номер, который вы действительно хотите, в зависимости от того, что вы подразумеваете под «размером файла» и содержимым файла. В определенном порядке:

В Windows, если вы открываете файл в текстовом режиме, цифры, которые вы получаете от ftell в этом файле, не являются байтовыми смещениями с самого начала файла; они больше похожи на файлы cookie fgetpos , которые могут использоваться только при последующем вызове fseek . Если вам нужно искать в текстовом файле в Windows, вам может быть лучше открыть файл в двоичном режиме и иметь дело с обеими линиями DOS и Unix самостоятельно — это на самом деле моя рекомендация для производственного кода в целом, потому что это вполне возможно иметь файл с окончанием строки DOS в системе Unix или наоборот.

В системах, где long int — 32 бита, файлы могут быть легко больше, а в этом случае ftell будет работать, возвратите -1 и установите errno в EOVERFLOW . Системы, совместимые с POSIX.1-2001, предоставляют функцию под названием ftello которая возвращает количество off_t которое может представлять более крупные размеры файлов, при условии, что вы установите #define _FILE_OFFSET_BITS 64 в самый верх всех исходных файлов (до любого #include s). Я не знаю, что такое эквивалент Windows.

Если ваш файл содержит символы, находящиеся за пределами ASCII, то количество байтов в файле, скорее всего, будет отличаться от количества символов в файле. (Например, если файл закодирован в UTF-8, символ 啡 будет занимать три байта, Ä будет занимать два или три байта в зависимости от того, будет ли он «составлен», а జ్ఞా за двенадцать байт, потому что, несмотря на то, что это единственная графема, это строка из четырех кодовых точек Unicode.) ftell(o) все равно скажет вам, что правильный номер передается в malloc , если ваша цель — прочитать весь файл в памяти, но итерация над «символами» будет не так проста, как for (i = 0; я .

Если вы используете «широкие потоки» C «и» широкие символы «, то, как и текстовые потоки в Windows, цифры, которые вы получаете от ftell в этом файле, не являются байтовыми смещениями и могут быть не полезны ни для чего, кроме последующих вызовов fseek , Но широкие потоки и персонажи — плохая конструкция; вы, скорее всего, сможете правильно обрабатывать все языки мира, если будете придерживаться обработки UTF-8 вручную в узких потоках и символах.

Илон Маск рекомендует:  Php руководство по рнр 3 0 почтовые функции
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL