Я сохранил размер файла в двоичном файле и могу поместить его в буфер 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;
}
2
user1527491 7 Фев 2015 в 18:11

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;
}
1
Community 23 Май 2017 в 12:12

Предполагая, что файл, содержащий размер файла, был создан на ТОЧНОМ компьютере И что он был изначально написан с типом off_t, вы можете просто преобразовать char[] -> off_t. например:

off_t filesize = *((off_t*)str);
-1
user590028 7 Фев 2015 в 15:40
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

0
Grady Player 7 Фев 2015 в 15:57

Просто скопируйте данные, о которых идет речь:

#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 ++?

1
Community 23 Май 2017 в 11:57