Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как преобразовать int/float/double в char *-строку, Тема - кандидат в FAQ 
:(
    Опции темы
zkv
Дата 27.12.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Преобразование переменной типа int (unsigned, float, double etc.) в char *, и обратно

С этим вопросом на начальном этапе сталкиваются практически все.
Выглядит он примерно так:
Код

//у меня есть переменная:
int var = 42;
//я хочу преобразовать ее в строку "42" (char *):
char *str;
//пытаюсь сделать так:
char *str = (char *)var;
//но ничего не получается :(

Приведенный выше пример некорректен, дело в том, что автор хотел выполнить конвертацию, а сделал приведение типа int к char *.
Выполнить конвертацию можно с помощью sprintf()itoa() (язык С), std::ostringstreamboost::format (язык С++), также можно попытаться проделать это вручную.
Я не буду заострять внимание на том, как использовать эти функции, умение придет с опытом, лучше попробую раскрыть суть проблемы.


Способ хранения С-строк (char *) в памяти компьютера. Конвертирование вручную.

Все данные в памяти хранятся в числовом выражении, будь то цифры, символы, картинки и т.д. и т.п.
Различия начинаются только при выводе данных, на монитор, принтер и т.п., то есть при из визуализации.
Получается компьютер не рисует у себя в памяти символы А Б В а записывает их код.
Для каждого символа он узнает этот код из таблицы символов.
Таблица символов представляет из себя набор пар символ<->код, каждое соотношение взаимооднозначное.
Таблицу символов также часто называют кодировкой.
Существует множество различных кодировок, в разных кодировках отдельный символ может представляться разным количеством бит (я, например, слышал только о 8-битных и 16-битных кодировках).
Как бы то ни было, здесь мы рассматриваем только ASCII-кодировку, будем считать, что она 8-битная (и 1-байтная smile), подробнее про остальные можете узнать здесь.
Итак, каждый символ в памяти - это некоторое числовое значение (код символа), узнать его можно, например, попросив компилятор рассматривать его как целое число, а не как символ:
Код

char c = '0';
cout<<(int)c;//выведет 48 - код символа '0'

это предотвратит подстановку визуального отображения символа вместо его кода.
В арифметических операциях никаких приведений вообще не нужно, вычислим, к примеру, расстояние между символами '0' и '9' в таблице:
Код

int diff =  '9' - '0';
cout<<diff; //выведет число 9

Строка же представляет из себя последовательность кодов символов, заканчивающихся нуль-символом: '\0' (обратный слэш информирует о начале escape-последовательности), те символом с кодом 0, этот символ нужен для определения конца строки.
При формировании строки вручную, очень важно не забывать добавлять его, иначе ваша программа может начать выводить всякую бяку, может портить данные, может вообще рухнуть.
В качестве примера* попробуем перевести введенное пользователем целое число в его строковое представление.
Я делаю это только в демонстрационных целях,  в реальных проектах лучше не привязывать себя к конкретным реализациям строк, а использовать готовые, протестированные решения.
В этом примере, мы воспользуемся тем, что коды символов цифр ('0', '1', '2' и т.д.) следуют друг за другом непрерывно, и упорядоченно по возрастанию, начиная с нуля (чувствуете, как мы привязываем свое решение к конкретной таблице символов, никто не гарантирует, что это утверждение верно для всех таблиц)
Код

#include<iostream>
#include<cmath>

int main()
{
    //запрашиваем переменную:
    int var = 0;
    std::cout<<"Input integer positive number for converting: ";
    std::cin>>var;
    //проверяем
    if( var <= 0 )
    {
        std::cout<<"\nThis example works with integer positive numbers only";
        return -1;
    }
    //вычислим количество циферок в числе
    int len = (int)std::log10( (double)var ) + 1;
    //выделяем память под строку (не забываем по нуль-символ уголок отвести):
    char *str = new char[ len + 1 ];
    //цикл по всем цифрам, начиная с последней
    for( int i = len-1; i >= 0; --i )
    {
        //получаем числовое значение последней(!) цифры в числе
        int digit = var % 10;
        //а вот и наш трюк, мы используем код символа '0' для того
        //чтобы получить код текущей цифры
        str[i] = '0' + digit;
        //"отбрасываем" последнюю цифру
        var /= 10;
    }
    //теперь в str лежит строковое представление введенного числа
    //осталось только приписать нуль-символ
    str[len] = '\0';
    //выведем то, что получилось
    std::cout<<"String is \""<<str<<"\"";
    //Поел - убери за собой!
    delete[] str;
}



Способы доступа к С-строкам. Что такое приведение типов.

Доступ к С-строке осуществляется посредством указателя на ее первый символ.
То есть в таком примере:
Код

    const char *str = "The String";

в переменной str записано число - адрес первого символа строки (буквы 'T'),
другими словами str - указывает на символ 'T' строки (вернее строкового литерала*, в данном случае) The String
почему-же тогда при выполнении такого кода:
Код

    const char *str = "The String";
    std::cout<<str;

компилятор выводит The String а не это число?
Все просто: вывод переменных типа char * производится по специальному правилу:
выводится первый символ по адресу, записанному в переменной, затем указатель "перенацеливается" на следующий символ  (инкрементируется), символ выводится, и так далее, пока не встретим нуль-символ - '\0' (что означает - строка закончена).
То, что пытался сделать воображаемый  программист в начале топика:
Код

    char *str = (char *)var; //ТАК НЕЛЬЗЯ!

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


Конвертирование в стиле языка С.

Имеем два варианта:
Код

//возвращает количество записанных в строку символов или -1 если произошла ошибка
int sprintf( char *buffer,                     //строка в которую записываем результат
                 const char *format,          //формат ввода 
                 ... );                                  //ряд переменных, для записи в строку

и
Код

//возвращает указатель на строку-результат в строку символов или -1 если произошла ошибка
char *  itoa ( int value,  //число для конвертации
                     char * str, //указатель на строку-результат - тоже самое, что и в возвращаемом значении
                     int base ); //основание системы счисления, в которой будет представлено число при выводе

Первый вариант лучше, тем, что он стандартный (те обязан присутствовать в библиотеках любого ANSI-C компилятора), поддерживает форматированный вывод, что обеспечивает большую гибкость вывода данных, поддерживаемые форматы можно подглядеть в описании функции printf()
Пример для sprintf()***:
Код

#include <stdio.h>

int main()
{
    char strOut[200];//сюды будем записывать
    
    float a = 2.4f;      //числа для конвертации
    int b = 3;
    //формат  %f - для float %d - для целых
    sprintf( strOut, "Если сложить %f и %d то получим %f", a, b, a+b );
    //выведем результат    
    printf( strOut ); 

    getc( stdin );
}

Функция же itoa() - не стандартная, но довольно распространенная, некоторые считает ее более удобной, хотя мне sprintf() симпатичнее ;). Но у нее есть одно преимущество: возможность представлять число при выводе в заданной системе счисления (я встречал информацию, поддерживаются основания от 2 до 32, но определенно все равно сказать ничего нельзя, по скольку стандарт насчет этой функции молчит).
Ну и пример (не мудрствуя лукаво скопировал из ссылки):
Код

/* itoa example */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  int i;
  char buffer [33];
  printf ("Enter a number: ");
  scanf ("%d",&i);
  itoa (i,buffer,10);
  printf ("decimal: %s\n",buffer);
  itoa (i,buffer,16);
  printf ("hexadecimal: %s\n",buffer);
  itoa (i,buffer,2);
  printf ("binary: %s\n",buffer);
  return 0;
}



Конвертирование в стиле языка С++.

Начнем конечно со stringstream, конкретно в нашей задаче - ostringstream (первая буква 'o' говорит нам, что это поток вывода). Это стандартный класс для работы со строковыми потоками****, со всеми вытекающими плюсами.
Пример:
Код

#include <iostream>
#include <sstream>

int main()
{
    //создаем строковый поток вывода, изначально он пуст
    std::ostringstream sstr;
    //переменные для конвертации
    float a = 2.4f;
    int b = 3;
    //выводим наши числа в поток, напоминает вывод через std::cout ;)
    sstr<<"Если сложить "<<a<<" и "<<b<<" то получим "<<a+b<<", а не "<<5;
    //выведем содержимое потока в консоль
    std::cout<<sstr.str();
}


Ну и остался boost::format, признаюсь, что сам с ним не работал - не возникало такой необходимости, так как вполне устраивал stringstream, по-этому за дальнейшей информацией и примерами по нему прошу в документацию.


Обратная конвертация (из строки в число).

Это действо можно назвать парсингом строки. 
Здесь используются аналогичные инструменты: sscanf() и atoi() для C, и istringstream для C++. Описывать их я не буду, примеры приводить тоже, все делается аналогично приведенным выше инструментам, так что вы справитесь с ними без труда.

Примечания.

*...В качестве примера... - если вы скомпилируете и запустите этот пример, то он скорее всего выполнится быстрее, чем вы сможете заметить результаты его работы, как это исправить рассказано (будет?) в другом топике в это FAQ.
**...вернее строкового литерала... - не нашел подходящей ссылки с описанием, что есть строковый литерал, есть у кого на примете? 
***...Пример для sprintf()... - а в этом примере неправильно будут отображаться русские буквы в консоли, что делать - описано (будет?) в соседнем топике
****...класс для работы со строковыми потоками... - в данной ссылке описан класс strstream который считается устаревшим и нерекомендован к использованию.

________________________________________________________________________________

Прилагаю "исходник" статьи, если кто-то хочет предложить свой вариант. (FireFox обзывает кодировку приложенного файла "Кириллица (Windows-1251)")

Да, если нетрудно, то плиз покажите места, где текст труднодоступный, буду переформулировать по возможности.
Здесь, кстати, больше интересует мнение неискушенных в вопросе программистов.

Назад к FAQ

Это сообщение отредактировал(а) bsa - 26.7.2011, 11:03

Присоединённый файл ( Кол-во скачиваний: 60 )
Присоединённый файл  faq_int_to_string.txt 11,53 Kb
PM MAIL   Вверх
Fazil6
Дата 27.12.2007, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



парни, вы разве факов раньше не видели? Обычно открыв фак имеешь по 2-3 вопроса с ответами на странице. Ну не нужны такие статьи. Куча лирики и мало конкретики. Рассматриваем строковый вывод числа - значит четко как и куда. Нафига лепить в кучу ввод, вывод, приведение типов и прочее? В итоге толком ни-то-ни-сё. Напишите лучше несколько маленьких статей каждая на узкую тему. Еще, если пишете для полных ламеров (а данная статья расчитана именно на таких судя по количеству вылитой воды) , то встретив в первом абзаце фразы типа
Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
узнать его просто, можно, например, привести символ к целому при выводе

то 99.9 из ста дальше читать не станут и в ужасе отложат эту статью подальше.

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


Это сообщение отредактировал(а) Fazil6 - 27.12.2007, 19:34
PM MAIL   Вверх
JackYF
Дата 27.12.2007, 19:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



zkv, мне понравилось. Основательный подход к делу.
Единственное - навскидку - можно ещё сказать про boost::lexical_cast. А так - молодец.

Добавлено @ 19:36
Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
Куча лирики и мало конкретики.

Не согласен. Будет - одна конкретика - так и не будет ничего знать новичок про то, что делает. Использовать функционал надо с умом и пониманием.

<cut by archimed7592>

Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
что это массив

да, возможно, стоит упомянуть. Но ставить во главу угла, имхо, не требуется.


Это сообщение отредактировал(а) archimed7592 - 27.12.2007, 20:08


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
zkv
Дата 27.12.2007, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
парни, вы разве факов раньше не видели? Обычно открыв фак имеешь по 2-3 вопроса с ответами на странице. Ну не нужны такие статьи. Куча лирики и мало конкретики. Рассматриваем строковый вывод числа - значит четко как и куда. Нафига лепить в кучу ввод, вывод, приведение типов и прочее? В итоге толком ни-то-ни-сё. Напишите лучше несколько маленьких статей каждая на узкую тему.

да, мне тоже так показалось, когда увидел все в целом, посмотрим что скажут остальные, и будем разбивать если что.  smile 
Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
Еще, если пишете для полных ламеров (а данная статья расчитана именно на таких судя по количеству вылитой воды) , то встретив в первом абзаце фразы типа

да, если нетрудно, то плиз покажите места, где текст труднодоступный, буду переформулировать по возможности.
Здесь, кстати, больше интересует мнение неискушенных в вопросе программистов
Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
И кстати раз уж зашел разговор о C-строке, то немешало бы упомянуть, что это массив и дальше уже плясать от этого определения

учтем
Цитата(JackYF @  27.12.2007,  19:34 Найти цитируемый пост)
Единственное - навскидку - можно ещё сказать про boost::lexical_cast.

учтем

Добавлено @ 19:43
Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
узнать его просто, можно, например, привести символ к целому при выводе

заменил на:
Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
узнать его можно, например, попросив компилятор рассматривать его как целое число, а не как символ:

 smile 

Это сообщение отредактировал(а) zkv - 27.12.2007, 19:47
PM MAIL   Вверх
Fazil6
Дата 27.12.2007, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
Способ хранения С-строк (char *) в памяти компьютера. Конвертирование вручную.

я бы не стал спорить о том есть здесь ошибка или нет, но то, что упомянуто в скобках , по меньшей мере небрежность и лучше это вообще убрать
Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
Я делаю это только в демонстрационных целях,  в реальных проектах лучше не привязывать себя к конкретным реализациям строк, а использовать готовые, протестированные решения.

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

Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
компилятор выводит The String а не это число?Все просто: вывод переменных типа char * производится по специальному правилу:выводится первый символ по адресу, записанному в переменной, затем указатель "перенацеливается" на следующий символ  (инкрементируется), символ выводится, и так далее, пока не встретим нуль-символ - '\0' (что означает - строка закончена).

понятно, что для новичков, но всетаки давайте не доходить до абсурда, всетаки не для детского сада... Перегрузка конкретного оператора тут, и вообще мне кажется, что статья посвященная преобразованию числа в строку чересчур злоупотребляет выводом на экран.
PM MAIL   Вверх
zkv
Дата 27.12.2007, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Fazil6, спасибо за замечания!
Цитата(Fazil6 @  27.12.2007,  20:14 Найти цитируемый пост)
я бы не стал спорить о том есть здесь ошибка или нет, но то, что упомянуто в скобках , по меньшей мере небрежность и лучше это вообще убрать

думаю, как-то надо обозначить, что речь идет именно о том, что люди хотят услышать. Так и правда не однозначно получилось, подумаю как будет лучше (в заголовке особенно не распишешься)

Цитата(Fazil6 @  27.12.2007,  20:14 Найти цитируемый пост)
эту мысль помоему надо как-то подругому озвучить, а то так прямо и подмывает продолжить чем нибудь типа "выпьем, няня, где же кружка?..."

то есть фамильярно слишком или что?  smile 
Цитата(Fazil6 @  27.12.2007,  20:14 Найти цитируемый пост)
понятно, что для новичков, но всетаки давайте не доходить до абсурда, всетаки не для детского сада... Перегрузка конкретного оператора тут

принято. сделаю примечание  smile 
Цитата(Fazil6 @  27.12.2007,  20:14 Найти цитируемый пост)
и вообще мне кажется, что статья посвященная преобразованию числа в строку чересчур злоупотребляет выводом на экран. 

это так, нужно стараться объяснить в контексте тех вещей, с которыми люди уже знакомы.

Внесением исправлений постараюсь заняться завтра, а то вымотался сегодня уже с этой статьей. Пока копим критику  smile 

Это сообщение отредактировал(а) zkv - 27.12.2007, 20:34
PM MAIL   Вверх
Fazil6
Дата 27.12.2007, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(zkv @  27.12.2007,  20:27 Найти цитируемый пост)
думаю, как-то надо обозначить, что речь идет именно о том, что люди хотят услышать. Так и правда не однозначно получилось, подумаю как будет лучше (в заголовке особенно не распишешься)

можно дать вначале четкое определение и дальше писать "С-строка" и поменьше отождествлять строку с указателем, типа: 
Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
 const char *str = "The String";    
std::cout<<str;


Добавлено через 8 минут и 53 секунды
Цитата(zkv @  27.12.2007,  20:27 Найти цитируемый пост)
то есть фамильярно слишком или что? 

нет. Не в этом дело. Не знаю как объяснить. 
Воспринимается так в контексте,  как тост венчающий все предыдущие размышления и прямо думаешь читая : "Аминь. Это я запомню на всю оставшуюся жизнь..."
PM MAIL   Вверх
Ln78
Дата 28.12.2007, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



Как обещал, поучаствую в обсуждении. Хотя в Новогодние праздники времени было бы больше, сейчас, в основном, перечислю то, что хотелось бы увидеть. Но начну с замечания о «замечаниях о стиле». Как-то уж слишком большое внимание уделяется этому вопросу, ИМХО, излишнее. По большому счёту, мы все не Пушкины и даже не Петзолды, чтобы критиковать чужой стиль изложения. По мне, так должно быть и больше лирики, и больше фактического содержания. Рассчитывать на то, что это будут статьи, каких ещё свет не видывал, вряд ли стоит, нужно быть реалистами. А «придраться» по стилю можно почти к любому посту. Например, в первом же  комментарии:
Цитата(Fazil6 @  27.12.2007,  19:33 Найти цитируемый пост)
то 99.9 из ста дальше читать не станут и в ужасе отложат эту статью подальше.

если речь идёт о процентах, то нужно писать знак процента, а сто можно и не писать, и так понятно, а если о людях (ламерах), то ужас от страшной судьбы того сотого, одна десятая которого продолжила чтение, в то время как остальная часть занялась чем-то другим.  smile 
Собственно, о содержании. Пока из перечисленного в заголовке изложено в основном преобразование целого в символьный вид. Кстати, у ‘0’ всё-таки код 48, а не 49. Хотелось бы побольше и про обратное преобразование, оптимизм в оценке возможностей читателя, конечно, хорошо, но несколько примеров, были бы не лишними. Поскольку в статье упоминались (и это хорошо) функции с возможностями преобразования с учётом системы счисления, то и обратные функции вроде strtoul тоже заслуживают своей доли известности. Пояснить, почему есть функция atof, а обратной для неё нет, перейдя, таким образом к форматированию вообще. 
Упоминание о бусте есть, а о других возможных классах, специфичных для разных сред разработки нет. Мне кажется, что и такие классы, как CString в MFC/ATL тоже следует назвать. Я уже однажды предлагал рассмотреть задачу вывода
 
Код

     double a=12,b=13,c=14,d=15,e=16;
      int i = 10, j = 20;
      char buffer[100];
      sprintf( buffer, "i=%4d, a=%6.2lf, b=%.5lf, c=%10.6le, d=%.3le, j=%d, e=%lg", i , a, b, c, d, j, e  );

как своего рода «Здравствуй, мир!», чтобы продемонстрировать, как её можно решить наиболее распространёнными способами. В том числе, было бы весьма полезно привести табличку по каждому из рассмотренных вариантов с указанием времени, нужного для преобразования, комментариями о преимуществах и недостатках, например, о том, что для той же CString не нужно заботиться о выделении достаточного объёма памяти, или о непонятной мне робости в вопросах типобезопасности (по мне, так как раз уж в функциях вывода ошибки с неправильной типизацией выявить и устранить наиболее просто).
Было бы хорошо сказать, что кроме char могут быть и юникодовские кодировки, сказав и про макрос _T, и про аналоги функций, для работы не только с ANSI-символами, т.е. про функции типа _stprintf. 


Это сообщение отредактировал(а) Ln78 - 28.12.2007, 08:42
PM MAIL   Вверх
zkv
Дата 28.12.2007, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
Кстати, у ‘0’ всё-таки код 48, а не 49. 

память подвела smile
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
Хотелось бы побольше и про обратное преобразование, оптимизм в оценке возможностей читателя, конечно, хорошо, но несколько примеров, были бы не лишними. 

ожидал реакции, что слишком объемным материал получается, по-этому не стал пока расписывать. Учту.
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
то и обратные функции вроде strtoul тоже заслуживают своей доли известности. Пояснить, почему есть функция atof, а обратной для неё нет, перейдя, таким образом к форматированию вообще. 

ок, посмотрю, учту. 
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
Мне кажется, что и такие классы, как CString в MFC/ATL тоже следует назвать.

гм, спорно, если рассматривать CString, тогда нужно и про AnsiString рассказать, и про QString, что еще у нас есть?
А буст таки почти стандарт
Хотя просто перечислить со ссылками можно.  smile 
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
или о непонятной мне робости в вопросах типобезопасности (по мне, так как раз уж в функциях вывода ошибки с неправильной типизацией выявить и устранить наиболее просто).

поясни пожалуйста, о чем речь?
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
Было бы хорошо сказать, что кроме char могут быть и юникодовские кодировки, сказав и про макрос _T, и про аналоги функций, для работы не только с ANSI-символами, т.е. про функции типа _stprintf. 

это, думаю, слишком обширная тема, и заслуживает отдельной статьи, здесь достаточно будет оставить ссылку на нее, пока постараюсь найти ссылку на сторонний материал.
Цитата(Ln78 @  28.12.2007,  08:36 Найти цитируемый пост)
В том числе, было бы весьма полезно привести табличку по каждому из рассмотренных вариантов с указанием времени, нужного для преобразования, комментариями о преимуществах и недостатках, 

Про затрачиваемое время сомневаюсь, что хорошая идея. 
по-моему, это вопрос оптимизации и только, а она, как известно, корень всех зол.
Если чел не может отличить приведение типов от конвертации (а зачем иначе он сюда пришел?) то не время еще заниматься вопросами оптимизации, основы языка для начала подучить бы, да стиль выработать.
Я даже склоняюсь скорее к тому, чтобы сказать: "Забудьте про быстродействие, используйте то, что вам понятнее/удобнее"

Я вообще уже думаю, что неплохо было бы вынести "Способ хранения" и "Способ доступа" в отдельные темы, а во всех темах, касающихся строк ссылаться на них? 
А то и правда тема получается "все обо всем".

P.S.
За исправления пока не берусь, думаю правильней будет подождать еще мнений. 
Пойду пока на баг охотиться  smile 

Это сообщение отредактировал(а) zkv - 28.12.2007, 09:24
PM MAIL   Вверх
Ln78
Дата 28.12.2007, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 274
Регистрация: 25.11.2006

Репутация: нет
Всего: 15



zkv, я думаю, что объёмный материал, это не так уж и страшно. Если речь идёт о достаточно подготовленном человеке, который забыл какую-то функцию, он посмотрит её в справке, MSDN'е. А если пришёл новичок, пусть уж не ленится, а прочитает и побольше, хуже не будет. Да и для более подготовленного тоже хотелось бы что-то иметь (для меня табличку со скоростями smile ).
Цитата(zkv @  28.12.2007,  09:20 Найти цитируемый пост)
гм, спорно, если рассматривать CString, тогда нужно и про AnsiString рассказать, и про QString, что еще у нас есть?

Так здесь я как раз именно за то, чтобы была обширная коллекция. Я понимаю, что тебе одному это сделать сложно, поскольку одновременно всем ты не пользуешься. Поэтому ещё раз призываю всех дополнить в комментариях своими способами решения задачи, а уж потом ты, приведя всё к единому стилю изложения, возьмёшь эти способы тоже. Такая сравнительная информация была бы полезна и новичкам и многим другим.
Цитата(zkv @  28.12.2007,  09:20 Найти цитируемый пост)
поясни пожалуйста, о чем речь

Возможно, я уже слишком стар и консервативен, но мне непонятны заявления, что printf/sprintf совсем плохи, тяжкое наследие C, в плюсах нужно использовать cout, он-де не имеет ошибок, как например, в случае:
Код

double a=12;
printf( "a=%4d", a );

 smile Мне лично cout не нравится именно из-за отсутствия в нём таких удобных символов форматирования, как в printf. 
А оптимизация - это совсем не зло. Например, я как-то писал программу, в которой нужно было выполнять преобразование символов в числа и наоборот для нескольких миллионов строк, и там это было весьма кстати. Там даже пришлось писать свою функцию преобразования шестнадцатеричного символьного представления в число, о корректности входных данных там мне заботиться не нужно было, поэтому и на этом тоже удалось сэкономить. smile Мне видится, что статьи должны быть не только для новичков (хотя большая часть должна быть для них), популярность изложения не должна обусловливать ограниченность содержания.
PM MAIL   Вверх
zkv
Дата 28.12.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: нет
Всего: 92



Ln78, большое спасибо за помощь!  smile 
Цитата(Ln78 @  28.12.2007,  10:12 Найти цитируемый пост)
Мне видится, что статьи должны быть не только для новичков (хотя большая часть должна быть для них), популярность изложения не должна обусловливать ограниченность содержания. 

Посмотрим, поддержат мнение твое или нет.
PM MAIL   Вверх
archimed7592
Дата 29.12.2007, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
она 8-битная (и 1-байтная smile), подробнее про остальные можете узнать здесь.

Думаю, что лучше дать эту ссылку smile.


Цитата(zkv @  27.12.2007,  19:11 Найти цитируемый пост)
Доступ к С-строке осуществляется посредством указателя на ее первый символ.

Вероятно, что здесь ты хотел подставить другую ссылку.


Теперь по содержимому.
1. Ессно нужно описать обратное преобразование.
2. boost и иже с ними идут фтопку. Это новички и заниматься установкой буста(пусть это и обыкновенное копирование одной папки в другую) им противопоказано.
3. Мне кажется, что нужно минимально описать способы "туда" и "обратно" для С и С++. Ручное преобразование можно оформить в отдельную статью.


Цитата(zkv @  28.12.2007,  10:25 Найти цитируемый пост)
Посмотрим, поддержат мнение твое или нет. 
Цитата(zkv @  28.12.2007,  09:20 Найти цитируемый пост)
Я вообще уже думаю, что неплохо было бы вынести "Способ хранения" и "Способ доступа" в отдельные темы, а во всех темах, касающихся строк ссылаться на них? 
А то и правда тема получается "все обо всем".

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

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

Оффтоп про правила был перенесён в тему Пишем правила

Это сообщение отредактировал(а) archimed7592 - 15.1.2008, 04:55


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
nk19
Дата 31.1.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 21.1.2008

Репутация: нет
Всего: нет



Вот у Эккеля нашел. Шаблон для преобразования в std::string и обратно для произвольного типа с операторами << >>
Код

//: C05:StringConv.h
// Шаблоны функций для преобразования в строку и обратно
#ifndef STRINGCONV_H
#define STRINGCONV_H
#include <string>
#include <sstream>

template<typename T>
T fromString(const std::string& s) {
  std::istringstream is(s);
  T t;
  is >> t;
  return t;
}

template<typename T>
std::string toString(const T& t) {
  std::ostringstream s;
  s << t;
  return s.str();
}
#endif // STRINGCONV_H ///:~

Пример использования
Код

//: C05:StringConvTest.cpp
#include <complex>
#include <iostream>
#include "StringConv.h"
using namespace std;

int main() {
  int i = 1234;
  cout << "i == \"" << toString(i) << "\"" << endl;
  float x = 567.89;
  cout << "x == \"" << toString(x) << "\"" << endl;
  complex<float> c(1.0, 2.0);
  cout << "c == \"" << toString(c) << "\"" << endl;
  cout << endl;

  i = fromString<int>(string("1234"));
  cout << "i == " << i << endl;
  x = fromString<float>(string("567.89"));
  cout << "x == " << x << endl;
  c = fromString< complex<float> >(string("(1.0,2.0)"));
  cout << "c == " << c << endl;
} ///:~

Результат такой:
Код

i == "1234"
x == "567.89"
c == "(1,2)"
 
i == 1234
x == 567.89
c == (1,2)

Если посчитаете нужным, включите в FAQ. Хотя это только обертка над ostringstream.
PM MAIL   Вверх
bsa
Дата 1.2.2008, 00:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



nk19, шаблоны для новичков?!? Ты что!
Если уж на то пошло, посмотри код шаблона boost::lexical_cast - удивишься его простоте и универсальности.
PM   Вверх
nk19
Дата 1.2.2008, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 21.1.2008

Репутация: нет
Всего: нет



bsa, не новички тоже могут FAQ читать - для систематизации знаний. Посмотрел lexical_cast, да лучше пример с ним привести, чем мой код.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1547 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.