четверг, 16 февраля 2012 г.

Я не знаю С++. sprintf()

Franz Ferdinand - Lindsey Wells
(Рекомендуется к прослушиванию)
 Сегодня я в очередной раз убедился в своем незнании языка C++. Вроде бы я пытаюсь кодить на нем уже 4 года, но мне кажется, что я знаю про него не больше 2%.
 В общем сегодня на тренировке всплыла следующая задача: "Как прибавить к строке число?"
Ясное дело, первое что пришло мне на ум - преобразовать число в строку и прибавить её к нашей изначальной строке. Код бы выглядел, наверное, примерно так:

#include <iostream>
#include <string>
using namespace std;
string reverse ( string str )
{
       string ans="";
       for ( int i=str.length()-1; i>=0; i-- )
           ans+=str[i];
       return ans;
}
string number_of_string ( int n )
{
       string ans="";
       while ( n!=0 )
       {
             ans+=(n%10)+'0';
             n/=10;
       }           
       return reverse(ans);   
}
int main()
{
    int n=121523;
    string str="Hello!";
    str+=number_of_string(n);
    return 0;
}

 Хотя, мне кажется, что даже эту реализацию можно было бы улучшить ( например, можно было бы не писать функцию reverse(), т.к. с помощью набора операций над строками можно обойтись и без нее )

К сожалению, данный код валится на куче тестах, а именно, при n<=0.
Таким образом, чтобы довести данный алгоритм до ума, потребуется явно больше времени, чем от этого можно было бы ожидать.

Тогда Человек Который Знает Все ( я, пожалуй, буду называть его так ), мягко нам намекнул, что данный метод является корявым и долгим в реализации, нам начали объяснять крутую реализацию этой задачи.

Как оказалось, вся соль заключается в чудесной функции С++ - sprintf().
Сам я про нее не очень много знаю, но попытаюсь что знаю рассказать:
Функция sprintf() работает почти также, как функция printf(), за исключением того, что printf() выводит данные в стандартный поток stdout, а sprintf() записывает данные в переменную, которая подается её на вход.

sprintf( char[] , "format", arguments... )


Таким образом выглядит функция sprintf(). 
char[] - это и есть тот массив символов, в который записывается строка вывода.
"format" - строка формата. Точно также, как в printf() в этой строке царствуют спецификаторы.
arguments - это те переменные, значения которых вы хотите увидеть на месте спецификаторов.

char str[100];
char username[]="Lindsey Wells";
sprintf(str, "Hello, %s!", username);

Таким образом, после выполнения функции sprintf(), переменная str примет вид:
str="Hello,  Lindsey Wells!"


Ну и теперь, после того как стало немного понятно, что из себя представляет функция sprintf(), становится очевидной реализация нашей задачи про сложения строки с числом:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    char str[100]="1+1/2+1/4+1/8+1/16+...=";
    int ans=2;
    char sum_str[100];
    sprintf(sum_str, "%s%i", str, ans);
    cout << sum_str;
    cin >> ans;
    return 0;
}

( кто не верит в верность полученного равенства, вот ссылка: 1+1/2+1/4...=2 )

Ну вот в общем и все, что я хотел рассказать. Как мне показалось на первый взгляд, функция sprintf() дает быстро реализовывать некоторые трудоемкие задачи.

1 комментарий:

  1. Прикольно написано, понравилось читать)
    Где-то я уже слышал про sprintf() (или про его аналог для cout), но тогда прочитал, не понял и забыл))

    ОтветитьУдалить