Я сохранил размер файла в двоичном файле и могу поместить его в буфер char[8]
. Я хотел бы преобразовать этот char[]
в тип off_t
, чтобы иметь возможность передавать его в качестве аргумента truncate(const char *path, off_t length)
.
Я пробовал этот наивный подход, и, кажется, большую часть времени он работает, но иногда он терпит неудачу и дает мне странную последовательность битов.
off_t pchar_2_off_t(char* str, size_t size)
{
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i)
{
ret <<= 8;
ret |= str[i];
}
return ret;
}
4 ответа
ret |= str[i];
является проблемой, поскольку str[i]
может расширяться по знаку при преобразовании в int
, устанавливая много битов в ret
. Подразумевается @pmg и прокомментировано @mafso
off_t pchar_2_off_t(const char* str, size_t size) {
off_t ret = 0;
size_t i;
for (i = 0; i < size; ++i) {
ret <<= 8;
ret |= (unsigned char) str[i];
}
return ret;
}
Предполагая, что файл, содержащий размер файла, был создан на ТОЧНОМ компьютере И что он был изначально написан с типом off_t
, вы можете просто преобразовать char[]
-> off_t
. например:
off_t filesize = *((off_t*)str);
unsigned const char blah[8] = {0xdd,0xee,0xaa,0xdd,0xbb,0xee,0xee,0xff};
off_t * scalar = (off_t *) malloc(8);
memcpy(scalar, blah, 8);
printf("%llx\n",*scalar);
Выходы (на моей машине Intel): ffeeeebbddaaeedd
Что за черт ?! вы говорите .... есть проблема с этим подходом, и это то, что он не переносится ... это проблема с порядок байтов...
Поэтому, если вы хотите сделать это переносимо, вам нужно либо знать о порядке байтов и особом случае, либо просто преобразовать с помощью цикла:
*scalar = 0;
for (int i = 0; i < 8; i++)
{
*scalar += (uint64_t)blah[i] << ( 8 * (7-i));
}
printf("%llx\n",*scalar);
Выходы (на всех машинах с 64-битными off_t): ddeeaaddbbeeeeff
Просто скопируйте данные, о которых идет речь:
#include <string.h> /* for memcpy() */
...
char str[8];
/* Read 8 bytes binary data into str here. */
off_t off_file;
memcpy(&off_file, str, sizeof off_file);
Чтобы обойти проблемы с бесконечностью, просто выполните:
off_t off = ntohll(off_file); /* Assuming ntohll being the 64bit version of ntohl(). */
Поскольку ntohll()
нестандартен, ознакомьтесь с некоторыми возможными способами его реализации здесь: 64-битный ntohl () в C ++? а>
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.