Evg |
СОДЕРЖАНИЕ
Форматная печать в Си и Си++
Запись от Evg размещена 16.10.2012 в 21:34
Показов 69861
Комментарии 7
1. Предисловие За основу была взята данная статья. Просто попытался немного изменить форму изложения, а так же добавить параллельное соответствие языков Си и Си++. Данную статью я рассматриваю как справочник с примерами, но не как учебник. При этом я рассматриваю вопрос в первую очередь с точки зрения проведения параллелей между языками Си и Си++. Возможности форматной печати в Си++ через std::cout более широкие, чем у Си'шного printf'а, и на данный момент я их не рассматриваю. При этом в std::cout отсутствует кое-что, что есть в printf'е, но в любом случае в Си++ есть возможность использования printf'а. Все примеры я исполнял на 32-битном linux'е. Следует понимать, что размеры базовых типов могут немного отличаться на разных системах, а потому на 64-битных или 16-битных системах результат может оказаться другим, либо может случиться так, что отсутствует тип long long или long double (см. статью Базовые типы в Си/Си++). Я так же опустил примеры с использованием типа signed char, поскольку работа с ним ведётся симметрично с типом char, т.к. char, в основном, совпадает с signed char'ом. Хотя в Си++ с точки зрения перегрузки функций типы char и signed char являются разными типами, при использовании в форматной печати с точки зрения пользователя каких-то тонкостей нет 2. Примеры форматной печати целочисленных величин 2.1. Печать целочисленных величин в десятичной системе счисления В языке Си при печати целочисленных величин используется следующее как бы правило: берётся некоторая форматная печать для типа int или unsigned int, а для всех прочих типов к указанному формату приделывается некоторый модификатор в соответствии с знаковостью типа. Это пишу для того, чтобы было понятно, что не надо пытаться выучить всю номенклатуру целочисленных форматов, а достаточно лишь понять общий принцип их построения и выучить только необходимое В Си есть ещё такая штука. Можно подать формат для печати типа int (%d), но при этом подать величину типа unsigned int. В итоге код окажется рабочим (без использования неинициализированных значений, без обращений к некорректным адресам памяти и т.п.). Единственное отличие от правильного формата (%u) будет печать величин с единицей в старшем разряде, поскольку %d и %u по разному будут трактовать такие величины. При печати маленьких значений разницы между %d и %u не будет и в большом количестве софта можно встретить такую нефатальную ошибку. В языке Си++ печать технически устроена совсем не так, как в Си. А потому для всех типов, за исключением char и unsigned char код печати при написании выглядит одинаково. Типы char и unsigned char при печати трактуются как символьные типы, а встроенной возможности распечатать их как целочисленные величины (как это есть в языке Си) отсутствует. Поэтому в примерах на C++ я не буду приводить код для всех типов, а только для char/unsigned char (поскольку они несимметричны с остальными типами) и int/unsigned int (все остальные типы печатаются по аналогии) Язык C
C #include <stdio.h> int main (void) { char c = -1; unsigned char uc = (unsigned char) c; short s = -2; unsigned short us = (unsigned short) s; int i = -3; unsigned u = (unsigned) i; long l = -4L; unsigned long ul = (unsigned long) l; long long ll = -5LL; unsigned long long ull = (unsigned long long) ll; printf ("char: %hhd\n", c); printf ("unsigned char: %hhu\n", uc); printf ("short: %hd\n", s); printf ("unsigned short: %hu\n", us); printf ("int: %d\n", i); printf ("unsigned: %u\n", u); printf ("long: %ld\n", l); printf ("unsigned long: %lu\n", ul); printf ("long long: %lld\n", ll); printf ("unsigned long long: %llu\n", ull); return 0; } Bash char: -1 unsigned char: 255 short: -2 unsigned short: 65534 int: -3 unsigned: 4294967293 long: -4 unsigned long: 4294967292 long long: -5 unsigned long long: 18446744073709551611 Язык C++
C++ #include <iostream> int main (void) { char c = -1; unsigned char uc = (unsigned char) c; int i = -3; unsigned u = (unsigned) i; std::cout << "char: " << (int) c << std::endl; std::cout << "unsigned char: " << (int) uc << std::endl; std::cout << "int: " << i << std::endl; std::cout << "unsigned: " << u << std::endl; return 0; } Bash char: -1 unsigned char: 255 int: -3 unsigned: 4294967293 2.2. Печать целочисленных величин в десятичной системе счисления с обязательным учётом знака Для языка Си продемонстрирую только для типа int, для остальных типов делается аналогичным образом. "Обычную" печать добавил для наглядного сравнения, каким образом печать прижимается к левому краю во всех случаях Язык C
C #include <stdio.h> int main (void) { int i1 = 5; int i2 = -5; printf ("Обычная печать без учёта знака:\n"); printf ("%d\n", i1); printf ("%d\n", i2); printf ("\nПечать с учётом знака:\n"); printf ("%+d\n", i1); printf ("%+d\n", i2); printf ("% d\n", i1); printf ("% d\n", i2); return 0; } Bash Обычная печать без учёта знака: 5 -5 Печать с учётом знака: +5 -5 5 -5 Язык C++
FIXME Для C++ не нашёл printf'овского аналога "% "
C++ #include <iostream> int main (void) { int i1 = 5; int i2 = -5; std::cout << "Обычная печать без учёта знака:" << std::endl; std::cout << i1 << std::endl; std::cout << i2 << std::endl; std::cout << std::endl << "Печать с учётом знака:" << std::endl; std::cout << std::showpos << i1 << std::endl; std::cout << std::showpos << i2 << std::endl; return 0; } Bash Обычная печать без учёта знака: 5 -5 Печать с учётом знака: +5 -5 2.3. Печать целочисленных величин в других системах счисления При печати чисел в системах счисления, отличных от десятичной, подразумевается беззнаковая величина. Потому что исторически так сложилось. Поэтому в примере я опускаю печати для знаковых величин (кроме char для C++): если вместо беззнаковых переменных подставить соответствующие им знаковые, то получим такой же результат. Это связано с тем, что отрицательные числа в "обычных" процессорах представлены в двоичном дополнительном коде Язык C
Bash 8-ричная СС: unsigned char: 377 unsigned short: 177776 unsigned: 37777777775 unsigned long: 37777777774 unsigned long long: 1777777777777777777773 16-ричная СС с строчными буквами: unsigned char: ff unsigned short: fffe unsigned: fffffffd unsigned long: fffffffc unsigned long long: fffffffffffffffb 16-ричная СС с заглавными буквами: unsigned char: FF unsigned short: FFFE unsigned: FFFFFFFD unsigned long: FFFFFFFC unsigned long long: FFFFFFFFFFFFFFFB Язык C++
C++ #include <iostream> int main (void) { char c = -1; unsigned char uc = (unsigned char) c; int i = -3; unsigned u = (unsigned) i; std::cout << "8-ричная СС:" << std::endl << std::endl; std::cout << "char: " << std::oct << (int)(unsigned char) c << std::endl; std::cout << "unsigned char: " << std::oct << (int) uc << std::endl; std::cout << "unsigned: " << std::oct << u << std::endl; std::cout << std::endl << "16-ричная СС с строчными буквами:" << std::endl << std::endl; std::cout << "char: " << std::hex << (int)(unsigned char) c << std::endl; std::cout << "unsigned char: " << std::hex << (int) uc << std::endl; std::cout << "unsigned: " << std::hex << u << std::endl; std::cout << std::endl << "16-ричная СС с заглавными буквами:" << std::endl << std::endl; std::cout << "char: " << std::hex << std::uppercase << (int)(unsigned char) c << std::endl; std::cout << "unsigned char: " << std::hex << std::uppercase << (int) uc << std::endl; std::cout << "unsigned: " << std::hex << std::uppercase << u << std::endl; return 0; } Bash 8-ричная СС: char: 377 unsigned char: 377 unsigned: 37777777775 16-ричная СС с строчными буквами: char: ff unsigned char: ff unsigned: fffffffd 16-ричная СС с заглавными буквами: char: FF unsigned char: FF unsigned: FFFFFFFD 2.4. Печать целочисленных величин с лидирующими нулями Для языка Си продемонстрирую только для типа int, для остальных типов делается аналогичным образом Язык C
Оба примера дадут один и тот же результат. Отличие только в том, что в первом примере величина минимального количества печатаемых знаков константная и задаётся прямо внутри форматной строки, а во втором примере - величина переменная и задаётся вне форматной строки
C #include <stdio.h> int main (void) { printf ("%.5d\n", 1); printf ("%.5d\n", 123); printf ("%.5d\n", 1234567); return 0; } C #include <stdio.h> int main (void) { int n = 5; printf ("%.*d\n", n, 1); printf ("%.*d\n", n, 123); printf ("%.*d\n", n, 1234567); return 0; } Bash 00001
00123
1234567Язык C++
Для Си++ отсутствует такая функциональность в явном виде, но она легко имитируется через задание ширины поля (см. раздел 6)
C++ #include <iostream> #include <iomanip> int main (void) { std::cout << std::setw(5) << std::setfill('0') << 1 << std::endl; std::cout << std::setw(5) << std::setfill('0') << 123 << std::endl; std::cout << std::setw(5) << std::setfill('0') << 1234567 << std::endl; return 0; }
3. Примеры форматной печати вещественных величин 3.1. Простая печать вещественных величин В языке Си для печати величин типа float и double используется один и тот же формат. Причины этого описаны здесь: При смене Float на double программа выдает нули В языке Си++ для всех вещественных форматов код программы будет выглядеть симметрично, а потому примеры буду приводить только для float'а Язык C
C #include <stdio.h> int main (void) { float f = 1.234F; double d = 2.345; long double ld = 3.456L; printf ("float: %f\n", f); printf ("double: %f\n", d); printf ("long double: %Lf\n", ld); return 0; } Bash float: 1.234000 double: 2.345000 long double: 3.456000 Язык C++
C++ #include <iostream> int main (void) { float f = 1.234F; std::cout << "Минимальное количество цифр после запятой:" << std::endl << std::endl; std::cout << "float: " << f << std::endl; std::cout << std::endl << "Фиксированное количество цифр после запятой (как это делается в printf'е):" << std::endl << std::endl; std::cout << "float: " << std::fixed << f << std::endl; return 0; } Bash Минимальное количество цифр после запятой: float: 1.234 Фиксированное количество цифр после запятой (как это делается в printf'е): float: 1.234000 3.2. Печать вещественных величин в экспотенциальной форме Язык C
C #include <stdio.h> int main (void) { float f = 1.234F; double d = 2.345; long double ld = 3.456L; printf ("С строчной буквой 'e':\n\n"); printf ("float: %e\n", f); printf ("double: %e\n", d); printf ("long double: %Le\n", ld); printf ("\nС прописной буквой 'E':\n\n"); printf ("float: %E\n", f); printf ("double: %E\n", d); printf ("long double: %LE\n", ld); return 0; } Bash С строчной буквой 'e': float: 1.234000e+00 double: 2.345000e+00 long double: 3.456000e+00 С прописной буквой 'E': float: 1.234000E+00 double: 2.345000E+00 long double: 3.456000E+00 Язык C++
C++ #include <iostream> int main (void) { float f = 1.234F; std::cout << "С строчной буквой 'e':" << std::endl << std::endl; std::cout << "float: " << std::scientific << f << std::endl; std::cout << std::endl << "С прописной буквой 'E':" << std::endl << std::endl; std::cout << "float: " << std::scientific << std::uppercase << f << std::endl; return 0; } Bash С строчной буквой 'e': float: 1.234000e+00 С прописной буквой 'E': float: 1.234000E+00 3.3. Печать вещественных величин с обязательным учётом знака Для языка Си продемонстрирую только для типа float, для остальных типов делается аналогичным образом. "Обычную" печать добавил для наглядного сравнения, каким образом печать прижимается к левому краю во всех случаях Язык C
C #include <stdio.h> int main (void) { float f1 = 123.25; float f2 = -123.25; printf ("Обычная печать без учёта знака:\n"); printf ("%f\n", f1); printf ("%f\n", f2); printf ("%e\n", f1); printf ("%e\n", f2); printf ("\nПечать с учётом знака:\n"); printf ("%+f\n", f1); printf ("%+f\n", f2); printf ("%+e\n", f1); printf ("%+e\n", f2); printf ("% f\n", f1); printf ("% f\n", f2); printf ("% e\n", f1); printf ("% e\n", f2); return 0; } Bash Обычная печать без учёта знака: 123.250000 -123.250000 1.232500e+02 -1.232500e+02 Печать с учётом знака: +123.250000 -123.250000 +1.232500e+02 -1.232500e+02 123.250000 -123.250000 1.232500e+02 -1.232500e+02 Язык C++
FIXME Для C++ не нашёл printf'овского аналога "% "
C++ #include <iostream> int main (void) { float f1 = 123.25; float f2 = -123.25; std::cout << "Обычная печать без учёта знака:" << std::endl; std::cout << std::fixed << f1 << std::endl; std::cout << std::fixed << f2 << std::endl; std::cout << std::scientific << f1 << std::endl; std::cout << std::scientific << f2 << std::endl; std::cout << std::endl << "Печать с учётом знака:" << std::endl; std::cout << std::fixed << std::showpos << f1 << std::endl; std::cout << std::fixed << std::showpos << f2 << std::endl; std::cout << std::scientific << std::showpos << f1 << std::endl; std::cout << std::scientific << std::showpos << f2 << std::endl; return 0; } Bash Обычная печать без учёта знака: 123.250000 -123.250000 1.232500e+02 -1.232500e+02 Печать с учётом знака: +123.250000 -123.250000 +1.232500e+02 -1.232500e+02 3.4. Печать вещественных величин с заданной точностью Для языка Си продемонстрирую только для типа float, для остальных типов делается аналогичным образом Язык C
C #include <stdio.h> int main (void) { float f = 1.234567; int n = 2; printf ("Обычная печать:\n"); printf ("%f\n", f); printf ("%e\n", f); printf ("Точность задана константой:\n"); printf ("%.2f\n", f); printf ("%.2e\n", f); printf ("Точность задана переменной:\n"); printf ("%.*f\n", n, f); printf ("%.*e\n", n, f); return 0; } Bash Обычная печать: 1.234567 1.234567e+00 Точность задана константой: 1.23 1.23e+00 Точность задана переменной: 1.23 1.23e+00 Язык C++
C++ #include <iostream> #include <iomanip> int main (void) { float f = 1.234567; std::cout << "Обычная печать:" << std::endl; std::cout << std::fixed << f << std::endl; std::cout << std::scientific << f << std::endl; std::cout << "Печать с точностью:" << std::endl; std::cout << std::fixed << std::setprecision(2) << f << std::endl; std::cout << std::scientific << std::setprecision(2) << f << std::endl; return 0; } Bash Обычная печать: 1.234567 1.234567e+00 Печать с точностью: 1.23 1.23e+00 4. Примеры форматной печати символьных величин Печать символа, представленного в виде char и печать символа, представленного как unsigned char выглядит между собой одинаково, что в языке Си, что в языке Си++. То же самое можно сказать про строки, представленные в виде char*, unsigned char*, char[] или unsigned char[]. Язык C
C #include <stdio.h> int main (void) { char c = 'a'; unsigned char uc = 'b'; char *cp = "abc"; unsigned char *ucp = "def"; char ca[] = "pqr"; unsigned char uca[] = "stu"; printf ("char: %c\n", c); printf ("unsigned char: %c\n", uc); printf ("char*: %s\n", cp); printf ("unsigned char*: %s\n", ucp); printf ("char[]: %s\n", ca); printf ("unsigned char[]: %s\n", uca); return 0; } Bash char: a unsigned char: b char*: abc unsigned char*: def char[]: pqr unsigned char[]: stu Язык C++
C++ #include <iostream> int main (void) { char c = 'a'; unsigned char uc = 'b'; char *cp = "abc"; unsigned char *ucp = (unsigned char*) "def"; char ca[] = "pqr"; unsigned char uca[] = "stu"; std::cout << "char: " << c << std::endl; std::cout << "unsigned char: " << uc << std::endl; std::cout << "char*: " << cp << std::endl; std::cout << "unsigned char*: " << ucp << std::endl; std::cout << "char[]: " << ca << std::endl; std::cout << "unsigned char[]: " << uca << std::endl; return 0; } Bash char: a unsigned char: b char*: abc unsigned char*: def char[]: pqr unsigned char[]: stu 5. Примеры форматной печати указателей В языке Си++ указатели char* и unsigned char* с любыми квалификаторами (const и volatile) при печати через std::cout трактуется как указатель на строку, а потому будет распечатываться как строка. Встроенной возможности для печати такого указателя как указателя (а не как строки) нету, а потому при печати требуется привести такие указатели к указателям на любой другой тип Язык C
C #include <stdio.h> int main (void) { int x; int *pi = &x; const char *pc = "abc"; printf ("%p\n", pi); printf ("%p\n", pc); return 0; } Bash 0xbf9b09dc 0x80484f0 Язык C++
C++ #include <iostream> int main (void) { int x; int *pi = &x; const char *pc = "abc"; std::cout << pi << std::endl; std::cout << (void*) pc << std::endl; return 0; } Bash 0xbfa0754c 0x8048840 6. Примеры управления шириной поля при форматной печати Управление шириной поля, как правило, требуется для аккуратной распечатки таблиц 6.1. Печать с заданной шириной поля Я здесь привожу пример для величины типа int. Для всех остальных типов печать делается симметрично. Отметим важный момент: если величина не влезает в поле, то поле расширяется Язык C
ВНИМАНИЕ! Квадратные скобки к формату НЕ относятся, они добавлены только для того, чтобы наглядно увидеть печатаемые пробелы и понять, где находятся границы поля
C #include <stdio.h> int main (void) { int i = 3; int j = 3456789; int n; printf ("Прижато к правому краю, ширина задаётся статически:\n"); printf ("[%5d]\n", i); printf ("[%5d]\n", j); printf ("[%05d]\n", i); printf ("[%05d]\n", j); printf ("\nПрижато к левому краю, ширина задаётся статически:\n"); printf ("[%-5d]\n", i); printf ("[%-5d]\n", j); printf ("\nПрижато к правому краю, ширина задаётся динамически:\n"); n = 4; printf ("[%*d]\n", n, i); printf ("[%*d]\n", n, j); printf ("[%0*d]\n", n, i); printf ("[%0*d]\n", n, j); printf ("\nПрижато к левому краю, ширина задаётся динамически:\n"); n = 4; printf ("[%-*d]\n", n, i); printf ("[%-*d]\n", n, j); return 0; } Bash Прижато к правому краю, ширина задаётся статически: [ 3] [3456789] [00003] [3456789] Прижато к левому краю, ширина задаётся статически: [3 ] [3456789] Прижато к правому краю, ширина задаётся динамически: [ 3] [3456789] [0003] [3456789] Прижато к левому краю, ширина задаётся динамически: [3 ] [3456789] Язык C++
C++ #include <iostream> int main (void) { int i = 3; int j = 3456789; std::cout << "Прижато к правому краю" << std::endl; std::cout << "[" << std::setw(5) << std::right << std::setfill(' ') << i << "]" << std::endl; std::cout << "[" << std::setw(5) << std::right << std::setfill(' ') << j << "]" << std::endl; std::cout << "[" << std::setw(5) << std::right << std::setfill('0') << i << "]" << std::endl; std::cout << "[" << std::setw(5) << std::right << std::setfill('0') << j << "]" << std::endl; std::cout << std::endl << "Прижато к левому краю" << std::endl; std::cout << "[" << std::setw(5) << std::left << std::setfill(' ') << i << "]" << std::endl; std::cout << "[" << std::setw(5) << std::left << std::setfill(' ') << j << "]" << std::endl; return 0; } Bash Прижато к правому краю [ 3] [3456789] [00003] [3456789] Прижато к левому краю [3 ] [3456789] 6.2. Печать строковых величин с подрезанием Такая функциональность позволяет печать подстроки когда работают не с высокоуровневым понятием "строка", а с низкоуровневым понятием "массив байтов" (которая необязательно заканчиывается нулём, но тем не менее длина известна). Язык C
ВНИМАНИЕ! Квадратные скобки к формату НЕ относятся, они добавлены только для того, чтобы наглядно увидеть отсутсвие пробелов после строки
C #include <stdio.h> int main (void) { int n; printf ("Размер задаётся статически:\n"); printf ("[%.5s]\n", "a"); printf ("[%.5s]\n", "abc"); printf ("[%.5s]\n", "abcdefgh"); n = 5; printf ("\nРазмер задаётся динамически:\n"); printf ("[%.*s]\n", n, "a"); printf ("[%.*s]\n", n, "abc"); printf ("[%.*s]\n", n, "abcdefgh"); return 0; }
Я не нашёл, как сделать подобное в C++. И это меня не удивляет. C++ - всё-таки язык высокого уровня с абстрактной единицей "строка", которая выражена в виде класса std::string. У строки легко взять подстроку нужной длины, а такого понятия, как незаконченная строка (что в Си будет выглядеть как массив char'ов, НЕ заканчивающихся нулём) быть не должно, ибо это понятие низкоуровневое 6.3. Примеры печати таблиц Таблица, ширина колонок которой задана статически Язык C
C #include <stdio.h> int main (void) { int n = 7; printf ("%*s %d\n", n, "a:", 10); printf ("%*s %d\n", n, "abc:", 100); printf ("%*s %d\n", n, "abcdef:", 1000); printf ("\n"); printf ("%-*s %d\n", n, "a:", 10); printf ("%-*s %d\n", n, "abc:", 100); printf ("%-*s %d\n", n, "abcdef:", 1000); return 0; } Bash a: 10 abc: 100 abcdef: 1000 a: 10 abc: 100 abcdef: 1000 Язык C++
C++ #include <iostream> int main (void) { int n = 7; std::cout << std::setw(n) << std::right << std::setfill(' ') << "a:" << " " << std::left << 10 << std::endl; std::cout << std::setw(n) << std::right << std::setfill(' ') << "abc:" << " " << std::left << 100 << std::endl; std::cout << std::setw(n) << std::right << std::setfill(' ') << "abcdef:" << " " << std::left << 1000 << std::endl; std::cout << std::endl; std::cout << std::setw(n) << std::setfill(' ') << "a:" << " " << std::left << 10 << std::endl; std::cout << std::setw(n) << std::setfill(' ') << "abc:" << " " << std::left << 100 << std::endl; std::cout << std::setw(n) << std::setfill(' ') << "abcdef:" << " " << std::left << 1000 << std::endl; return 0; } Bash a: 10 abc: 100 abcdef: 1000 a: 10 abc: 100 abcdef: 1000 Таблица, ширина колонок которой вычисляется динамически Язык C
Я бы сказал, что подобные коды шиты белыми нитками. В наше время стала актуальной работа с unicode'овскими строками (которых ещё не было в момент разработки стандарта Си), а потому такой код попросту не будет корректно учитывать мультибайтовые символы. Но тем не менее такую конструкцию я помещу в статью, чисто для самообразования
C #include <stdio.h> int main (void) { int n1, n2, n3, w1, w2, w3; printf (" Column1 %n| Column2 %n| Column3 %n|\n", &n1, &n2, &n3); w1 = n1; w2 = n2 - n1 - 1; w3 = n3 - n2 - 1; printf ("%-*s|%-*s|%-*s|\n", w1, "abc", w2, "de", w3, "fghijk"); printf ("%-*d|%-*d|%-*d|\n", w1, 123456, w2, 7, w3, -153); return 0; } Bash Column1 | Column2 | Column3 | abc |de |fghijk | 123456 |7 |-153 | Для C++ я не нашёл printf'овского аналога %n. И это, в общем-то, вполне логично. Функция печати, по хорошему, не должна заниматься никакой модификацией переменных. 7. Ссылки на темы, где обсуждался данный вопрос
8. Внешние ссылки по данной тематике
FIXME как-то объяснить, что плавающие числа печатаются с округлениями FIXME fprintf, sprintf | |||||||||||||||
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 7
Комментарии
-
хорошая заметка, только имеет некий налет "в С есть а вот в С++ нету". Для объективности стоило бы параллельно отмечать возможности и плюсы С++, а то на рекламу похоже.
Хотя пожалуй достаточно будет лишь одной ремарки. Все эти фичи языка С, они доступны в языке С++. Никто и никогда не накладывал табу на использование С-либ, там где это необходимо. Так что честно будет сказать так: в языке С доступна функция printf с ее возможностями, а в языке С++ доступна функция printf с ее возможностями и еще доступна библиотека потоков ввода-вывода, содержащая coutЗапись от Pure размещена 17.10.2012 в 20:41
-
Да, надо как-то эту мысль изложить в явном виде. По-хорошему надо ещё допилить разделы на предмет того, что можно только в Си++, ибо возможностей у cout'а заведомо больше, чем у printf'а
> "в С есть а вот в С++ нету"
Хрен его знает, может и есть. Просто в плюсах я плохо шарю, что смог - нашёл, но остались какие-то штуки, для которых не смог найти printf'овского аналогаЗапись от Evg размещена 17.10.2012 в 20:49
-
Запись от Pure размещена 17.10.2012 в 20:53
-
А куда signed char делся? Он тоже как символ печатается.Запись от Somebody размещена 17.10.2012 в 22:04
-
Запись от Evg размещена 18.10.2012 в 00:03
-
Запись от Evg размещена 21.10.2012 в 11:00
-
Запись от Croessmah размещена 26.11.2016 в 11:51


