LINUX.ORG.RU

Считывание данных из std в массив unsigned char*


0

1

Добрый день! Мне необходимо сформировать следующий пакет длиной 42 байта, представленный масиивом unsigned char: длина логина [1], логин[20], длина пароля[1], пароль[20] (в скобках указан размер в байтах). Логин и пароль пользователь вводит из std. Может быть, можно как-то заполнять структуру, а потом посредствм reinterpret_cast представить ее в виде массива из unsigned char. Затрудняюсь с реализацией. Не могли Вы привести код.


unsigned char packet[42];
*packet = login.size();
memcpy(packet+1, login.c_str(), login.size());
*(packet+21)= pass.size();
memcpy(packet+22, pass.c_str(), pass.size());
waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от ugoday

я, честно говоря, на поле «фром» только после твоего коммента посмотрел

waker ★★★★★
()

Не могли Вы привести код.

«Маша», с такими запросами я бы послал лесомв Job. Ты хоть с чем-нибудь само можешь разобраться? Как тебя на работу взяли вообще?

lazyklimm ★★★★★
()

смотри в сторону ostringstream

ostringstream ss;
ss<<(char)login.size()<<login<< /*итд.*/;
ss.str().c_str();


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

Да, кстати, как называется проект Мере, на котором ты делаешь пакеты, сервера и вот эти хэлоуволрды?

aol ★★★★★
()
Последнее исправление: aol (всего исправлений: 2)
Ответ на: комментарий от lazyklimm

Ты хоть с чем-нибудь само можешь разобраться? Как тебя на работу взяли вообще?

Может она студентка еще, а ты так по злому.

Dudraug ★★★★★
()
Ответ на: комментарий от Dudraug

Может она студентка еще

может, но судя по темам - маловероятно (кстати, у «неё» похоже обострение в середине-конце июля-августе, немного странное время для сдачи контрольных, не кажется?), даже если студентка, то работающая.

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

Собственно, в этом бы не было ничего страшного, если бы помощь как-то оплачивалась. А то ей тут разжевывают, кладут в рот по доброте душевной, а она (судя по всему) ещё и зарплату получает. Не, мне не жалко, но самим-то не обидно? Одно дело делиться знаниями с человеком, который стремится их получить, другое - преподносить готовый результат на блюдечке с голубой каёмочкой.

lazyklimm ★★★★★
()
Ответ на: комментарий от Dudraug

1. по условию было на размер 1 байт, так что твой пример некорректный
2. твой пример будет генерить разные данные на разных архитектурах (big/little endian)

waker ★★★★★
()
Ответ на: комментарий от waker

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

Dudraug ★★★★★
()

Я даже знаю для какой игры ты пишешь.

Jetty ★★★★★
()
Ответ на: комментарий от waker
    unsigned char packet[42] = { 0 };
    unsigned login_size = login.size() < 20 ? login.size() : 20;
    unsigned pass_size = pass.size() < 20 ? pass.size() : 20;
    packet[0] = login_size;
    memcpy(&packet[1], login.c_str(), login_size);
    packet[21]= pass_size;
    memcpy(&packet[22], pass.c_str(), pass_size);

а то сегфолт будет на больших строчках.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

слуш, ну я просто написал простейший пример на коленке. проверку переполнения и прочее — пусть уже ТС делает.

waker ★★★★★
()
Ответ на: комментарий от quasimoto
    size_t login_size = login.size() < 20 ? login.size() : 20;
    size_t pass_size = pass.size() < 20 ? pass.size() : 20;

А вообще, вроде как нет гарантии, что char (c_str возвращает const char*) всегда положителен.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

waker все правильно написал, проверка на размер должна быть проведена раньше, никаких:

unsigned login_size = login.size() < 20 ? login.size() : 20;

в принципе не должно быть, кому нужны некорректные данные?

wota ★★
()
Ответ на: комментарий от wota

проверка на размер должна быть проведена раньше

if (login.size() > 20)
    you_do_it_wrong();

? Можно копировать в packet только первые 20 байт строки если та большая, то есть передавать memcpy не login.size() а login.size() <= 20 ? login.size() : 20, тогда будет работать и для больших строк.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

?

да, пользователь ввел логин больше 20 символов - ему в ответ сразу ошибка

Можно копировать в packet только первые 20 байт строки
тогда будет работать и для больших строк.

зачем? эти данные дважды некорректны, во-первых потому изначально строка не может быть больше 20 символов, во-вторых потому-что в массив лягут не те данные, что ввел пользователь

wota ★★
()
Ответ на: комментарий от wota

Всё правильно, я испугался голого memcpy, но вместо нормальной проверки перед ним (если размеры и структура пакета определяются тут, то и проверка должна быть рядом) зачем-то отсёк кусок строки.

Для gcc/clang ещё можно сделать

struct packet {
    char login_size;
    char login[20];
    char pass_size;
    char pass[20];
} __attribute__((packed));

...

    if (login.size() > 20 || pass.size() > 20)
        ; // do something

    packet pack = { login.size(), { 0 }, pass.size(), { 0 } };
    memcpy(pack.login, login.c_str(), login.size());
    memcpy(pack.pass, pass.c_str(), pass.size());

и потом использовать (char*)&pack.

quasimoto ★★★★
()
Ответ на: комментарий от Jetty

Потому что принципиальные ошибки в коде.

Долго смотрел на код и искал принципиальные ошибки. Не смог найти. Поможешь найти?

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.