Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Преобпазование типов: std::string->unsigned char[]


Автор: Alca 1.11.2008, 23:52
Преобпазование типов: std::string -> unsigned char[]?

Строку:
Код

std::string sStr("01234567");

надо преобразовать в
Код

unsigned char ucBuffer[8];

Автор: J0ker 2.11.2008, 01:39
метод c_str() возвращает const char * для std::string

Автор: Alca 2.11.2008, 01:51
const char * это же не unsigned char[]

Автор: J0ker 2.11.2008, 02:03
нет таких типов T[] - либо должен быть размер массива больше нуля (для C++), либо это эквивалентно T* (если, конечно, переменная сразу не инициализированна массивом)
std::string - это массив char'ов
к const unsigned char* можно преобразовать
reinterpret_cast<const unsigned char *>(s.c_str());


Автор: Alca 2.11.2008, 02:20
Код

unsigned char ucBuffer[8] = reinterpret_cast<const unsigned char *>(csStr.c_str());

Код

error C2440: 'initializing' : cannot convert from 'const unsigned char *' to 'unsigned char [8]'

Автор: dumb 2.11.2008, 02:57
Alca, елы-палы. у тебя под тыщу сообщений, все примерно на одну тему, а АЗЫ никак не одолеем... smile
Код
strcpy(ucBuffer, csStr.c_str()); // без учета ограничения по длине. в "реальной жизни" так делать опасно.

Автор: J0ker 2.11.2008, 03:25
Цитата(Alca @ 2.11.2008,  02:20)
Код

unsigned char ucBuffer[8] = reinterpret_cast<const unsigned char *>(csStr.c_str());

Код

error C2440: 'initializing' : cannot convert from 'const unsigned char *' to 'unsigned char [8]'

нехорошо конвертировать const в неconst
но если приспичило
unsigned char *ucBuffer = const_cast<unsigned char>(reinterpret_cast<const unsigned char *>(csStr.c_str()));

Добавлено @ 03:27
тока предупреждаю - модифицировать данные по адресу ucBuffer нельзя - они принадлежат std::string  smile 

Автор: MAKCim 2.11.2008, 10:36
Цитата(J0ker @  2.11.2008,  02:03 Найти цитируемый пост)
std::string - это массив char'ов

никогда в жизни
std::string - это класс
реализация может быть разной  smile 

Автор: Lazin 2.11.2008, 12:19
Цитата(J0ker @  2.11.2008,  03:25 Найти цитируемый пост)
тока предупреждаю - модифицировать данные по адресу ucBuffer нельзя - они принадлежат std::string

мало того, они долго не проживут, поэтому нужно сначала выделить память в достаточном количестве, потом скопировать туда то, что возвращает c_str().

Автор: Alca 2.11.2008, 12:25
Какой вариант наиболее оптимальный?
Вариант 1:
Код

    std::string sStr("01234567");
    unsigned char ucBuffer[8];
    
    strcpy((char *)ucBuffer, sStr.c_str()); 

Вариант 2: (не уверен корректный ли)
Код

    std::string sStr("01234567");
    unsigned char ucBuffer[8];

    for (unsigned int i = 0; i < sStr.size(); i ++) {
        int iChar = sStr.at(i);    
        if (iChar < 0) {
            iChar = 256 + iChar;    //здесь iChar < 0
        } 
        ucBuff[i] = iChar;
    }

Автор: Lazin 2.11.2008, 12:26
вообще, можно и проще сделать
Код

std::string str("i am string");
std::vector<unsigned char> data;//i am array
std::copy(str.begin(), str.end(), std::back_inserter(data));

Автор: Cтpaнник 2.11.2008, 12:28
Дык, тогда уж зачем заморачиваться с выделением памяти "в достаточном количестве"?
Код

std::vector<unsigned char> v;
v.assign(reinterpret_cast<const unsigned char *>(csStr.begin()), reinterpret_cast<const unsigned char *>(csStr.end()));
// вуаля!

Автор: Lazin 2.11.2008, 12:29
Код

unsigned char* array = &data[0];
 smile 

Автор: mes 2.11.2008, 12:46
Цитата(Alca @  2.11.2008,  12:25 Найти цитируемый пост)
    std::string sStr("01234567");
    unsigned char ucBuffer[8];
    for (unsigned int i = 0; i < sStr.size(); i ++) {
        int iChar = sStr.at(i);    
        if (iChar < 0) {
            iChar = 256 + iChar;    //здесь iChar < 0
        } 

        ucBuff[i] = iChar;
    }

 smile  smile  smile 
Кто нибудь может разъяснить тайный смысл сего написанного ?

Автор: Alca 2.11.2008, 13:15
Цитата

Кто нибудь может разъяснить тайный смысл сего написанного ?

Ну типа того:
Код

    for (unsigned int i = 0; i < csStr.size(); i ++) {
        int iChar = (unsigned int)csStr.at(i);    
        ucBuff[i] = iChar;
    }

Автор: mes 2.11.2008, 13:24
Цитата(Alca @  2.11.2008,  13:15 Найти цитируемый пост)
    for (unsigned int i = 0; i < csStr.size(); i ++) {
        int iChar = (unsigned int)csStr.at(i);    
        ucBuff[i] = iChar;
    }

вот с какого боку там int iChar, когда  ucBuff типа  unsigned char.

во первых можно написать короче, без непонятно для чего нужного приведенния к int
Код

  for (unsigned int i = 0; i < csStr.size(); i ++)  { ucBuff[i]  = static_cast<unsigned char>(csStr.at(i)); }

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

Автор: Alca 2.11.2008, 13:51
А чем принципиальное отличие?
Код

    for (unsigned int i = 0; i < csStr.size(); i ++) {
        ucBuff[i] = (unsigned int)csStr.at(i);
    }

и
Код

    for (unsigned int i = 0; i < csStr.size(); i ++)  { 
        ucBuff[i]  = static_cast<unsigned char>(csStr.at(i)); 
    } 

Автор: mes 2.11.2008, 14:03
Цитата(Alca @  2.11.2008,  13:51 Найти цитируемый пост)
 ucBuff[i] = (unsigned int)csStr.at(i);

строчка не полна, и заставляет программиста лишний раз задуматься о происходящем, хотя никакой дополнительной нагрузки вышеупомянутый код не несет.

во первых если делаете преобразование , то старайтесь делать его точно. А так вы оставляете преобразование unsigned int->unsigned char на волю компилятора.
во вторых точное преобразование типа static_cast всегда лучше си-каста (использованного в Вашем примере).
 smile 

Автор: Alca 2.11.2008, 14:06
Спасибо.

Автор: JackYF 2.11.2008, 16:53
Тему пометил решённой.

Добавлено через 28 секунд
Нет, не пометил smile
Топикстартер, помечай.

Автор: J0ker 2.11.2008, 18:49
Цитата(MAKCim @ 2.11.2008,  10:36)
Цитата(J0ker @  2.11.2008,  02:03 Найти цитируемый пост)
std::string - это массив char'ов

никогда в жизни
std::string - это класс
реализация может быть разной  smile

отчасти согласен, но смею указать, что спецификация метода c_str() приводит к тому, что эффективная реализация string в 99.99999% - это все-таки массив

Автор: vinter 3.11.2008, 14:23
Цитата(J0ker @  2.11.2008,  19:49 Найти цитируемый пост)
отчасти согласен, но смею указать, что спецификация метода c_str() приводит к тому, что эффективная реализация string в 99.99999% - это все-таки массив

какая спецификация можети об этом говорить? c_str() возвращает сторонний буфер который умрет при любом изменении стринга, каким образом это связано с внутренностью стринга?

Автор: J0ker 3.11.2008, 17:53
Цитата(vinter @  3.11.2008,  14:23 Найти цитируемый пост)
какая спецификация можети об этом говорить?

никакая

Цитата(vinter @  3.11.2008,  14:23 Найти цитируемый пост)
c_str() возвращает сторонний буфер

обычно (во всяком случае я не видел других вариантов) c_str() добавляет '\0' в конец строки и возвращает указатель на свой внутренний буфер - иная реализация была-бы не эффективна

Автор: MAKCim 3.11.2008, 19:32
Цитата(J0ker @  3.11.2008,  17:53 Найти цитируемый пост)
обычно (во всяком случае я не видел других вариантов) c_str() добавляет '\0' в конец строки и возвращает указатель на свой внутренний буфер - иная реализация была-бы не эффективна 

ну как бы если мы используем С++ и std::string, то частое использование С-строк не приветствуется и говорит о кривости кода  smile 
поэтому c_str() в принципе не должен использоваться часто, а значит и реализация не обязана быть эффективной

Автор: J0ker 3.11.2008, 20:46
Цитата(MAKCim @ 3.11.2008,  19:32)
Цитата(J0ker @  3.11.2008,  17:53 Найти цитируемый пост)
обычно (во всяком случае я не видел других вариантов) c_str() добавляет '\0' в конец строки и возвращает указатель на свой внутренний буфер - иная реализация была-бы не эффективна 

ну как бы если мы используем С++ и std::string, то частое использование С-строк не приветствуется и говорит о кривости кода  smile 
поэтому c_str() в принципе не должен использоваться часто, а значит и реализация не обязана быть эффективной

а я разве говорил где-то про обязательства?
проясняю ситуацию
в связи с тем, что:
1. c_str() быть обязана
2. организация внутреннего буфера std::string в виде нэйтив массива ничему не препятствует в плане эффективности на большинстве современных архитектур
- внутренний буфер std::string организован обычно в виде массива

Автор: Lazin 3.11.2008, 21:00
Цитата(MAKCim @  3.11.2008,  19:32 Найти цитируемый пост)
ну как бы если мы используем С++ и std::string, то частое использование С-строк не приветствуется и говорит о кривости кода

я не согласен, многие интерфейсы используют const char* чтобы быть более универсальными, например, что-бы можно было написать так:
Код

void foo(const char*);
...
foo("blablabla");

иначе пришлось бы писать так:
Код

foo(std::string("blablabla"));
 smile

Добавлено через 1 минуту и 30 секунд
хотя нет, можно было-бы писать foo("blablabla") в любом случае, просто в случае std::string неявно был бы вызван конструктор smile 

Автор: MAKCim 3.11.2008, 22:29
J0ker, 
это все понятно
вопрос в чем вообще?
Цитата(J0ker @  2.11.2008,  02:03 Найти цитируемый пост)
std::string - это массив char'ов

Цитата(MAKCim @  2.11.2008,  10:36 Найти цитируемый пост)
никогда в жизни
std::string - это класс
реализация может быть разной


ты с чем-то не согласен?  smile 

Автор: J0ker 4.11.2008, 06:05
ладно, MAKCim, ты победил  smile 

Автор: JackYF 4.11.2008, 19:13
Вообще говоря, лишние конструкторы - лишнее падение производительности... ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)