Как преобразовать структуру в массив символов в C

В таком случае std :: initializer_list - лучший выбор.

class Foo{
public:
    Foo(int n, std::initializer_list a, std::initializer_list b);
};

Foo foo { 32, {}, { 2, 3, 1, 2 }};

Живой пример .

9
задан falcojr 12 January 2009 в 13:52
поделиться

10 ответов

x спецификатор формата отдельно говорит, что аргумент int, и так как число отрицательно, printf требует, чтобы восемь символов показали все четыре ненулевых байта int- размерное значение. 0 модификатор говорит для заполнения вывода нулями, и 2 модификатор говорит, что минимальный вывод должен быть двумя символами долго. Насколько я могу сказать, printf не позволяет указывать максимальную ширину, за исключением строк.

Теперь затем Вы только передаете a char, таким образом пустой x говорит функции использовать полное int это было передано вместо этого — из-за продвижения параметра по умолчанию для"..."параметры. Попробуйте hh модификатор, чтобы сказать функции рассматривать аргумент как просто a char вместо этого:

printf("%02hhx", b[i]);
8
ответ дан 4 December 2019 в 06:35
поделиться

символ является типом со знаком; таким образом с дополнением two, 0x80-128 для 8-разрядного целого числа (т.е. байт)

8
ответ дан 4 December 2019 в 06:35
поделиться

То, что Вы видите, является преобразованием сохранения знака от символа до интервала. Поведение следует из того, что в Вашей системе, символ подписывается (Примечание: символ не подписывается во всех системах). Это приведет к отрицательным величинам, если комбинация двоичных разрядов уступит отрицательной величине для символа. Продвижение такого символа к интервалу сохранит знак, и интервал будет отрицателен также. Обратите внимание на это, даже если Вы не помещаете a (int) явно, компилятор будет автоматически способствовать символу интервал при передаче printf. Решение состоит в том, чтобы преобразовать Ваше значение в unsigned char во-первых:

for (i=0; i<4; i++)
   printf("%02x ", (unsigned char)b[i]);

С другой стороны, можно использовать unsigned char* от запуска на:

unsigned char *b = (unsigned char *)&a;

И затем Вам не нужен никакой бросок в то время, когда Вы печатаете его с printf.

11
ответ дан 4 December 2019 в 06:35
поделиться

Обработка Вашей структуры, как будто это был массив символов, является неопределенным поведением. Для отправки его по сети используйте надлежащую сериализацию вместо этого. Это - боль в C++ и еще больше в C, но это - единственный способ, которым Ваше приложение будет работать независимо от чтения машин и записи.

http://en.wikipedia.org/wiki/Serialization#C

5
ответ дан 4 December 2019 в 06:35
поделиться

символ является типом со знаком поэтому, что Вы видите, представление с двумя комплиментами, бросание к (неподписанный символ*) зафиксирует это (Rowland просто победил меня).

На стороне отмечают, что можно хотеть измениться

for (i=0; i<4; i++) {
//...
}

кому:

for (i=0; i<sizeof(x); i++) {
//...
}
1
ответ дан 4 December 2019 в 06:35
поделиться

Можно хотеть преобразовать в неподписанный массив символов.

0
ответ дан 4 December 2019 в 06:35
поделиться

Если у Вас нет очень убедительных измерений, показывающих, что каждый октет драгоценен, не делайте этого. Используйте читаемый протокол ASCII как SMTP, NNTP или один из многих других прекрасных Протоколов Интернета, шифруемых IETF.

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

-1
ответ дан 4 December 2019 в 06:35
поделиться

При преобразовании структуры в символы или байты путем, Вы делаете его, собирается привести к проблемам, когда Вы действительно пытаетесь сделать это сетью нейтральный. Почему бы не решить ту проблему теперь? Существует множество различных методов, которые можно использовать, все из которых, вероятно, будут более "портативными", чем, что Вы пытаетесь сделать. Например:

  • С отправкой числовых данных по сети нейтральным в отношении машины способом долго имели дело, в мире POSIX/Unix, через функции htonl, htons, ntohl и ntohs. Посмотрите, например, byteorder (3) страница руководства в системе FreeBSD или Linux.
  • Преобразование данных к и от абсолютно нейтрального представления как JSON также совершенно приемлемо. Количество времени Ваши программы тратят преобразование данных между JSON и собственными формами, вероятно, побледнеет по сравнению с сетевыми задержками передачи.
2
ответ дан 4 December 2019 в 06:35
поделиться

Когда вы собираетесь отправить его, просто используйте:

(char *) & CustomPacket

для преобразования. Работает для меня.

1
ответ дан 4 December 2019 в 06:35
поделиться

Знаковость массива char не является корнем проблемы! (Это -а-проблема, но не единственная проблема.)

Выравнивание! Это ключевое слово здесь. Вот почему вы НИКОГДА не должны пытаться обращаться со структурами как с необработанной памятью. Компиляторы (и различные флаги оптимизации), операционные системы, фазы луны - все это делает странные и интересные вещи с фактическим расположением в памяти "соседних" полей в структуре. Например, если у вас есть структура с char, за которой следует int, вся структура будет занимать в памяти ВОСЕМЬ байт - char, 3 пустых, бесполезных байта, а затем 4 байта для int. Машине нравится делать такие вещи, чтобы структуры умещались на страницах памяти, и тому подобное.

Пройдите вводный курс по архитектуре машины в местном колледже. Между тем, сериализуйте правильно. Никогда не обращайтесь со структурами как с массивами char.

1
ответ дан 4 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: