Не зависят от конкретного компьютера Язык Си
Скачать 5.8 Mb.
|
getline(имя_строки, размер_строки): … int main() { setlocale(LC_ALL,"Rus"); char string[100] = ""; cout << "Ваша любимая цитата: "; cin.getline(string, sizeof(string)); cout << string << endl; … } Строки и символьные массивы Результат работы программы: Аналогичный результат получится при дополнении программы вводом с использованием функции get(имя_строки, размер_строки): … cin.get(string, sizeof(string)); … Строки и символьные массивы Дополним программу вводом с использованием функции getline() с тремя аргументами: … int main() { setlocale(LC_ALL,"Rus"); char string[100] = ""; cout << "Введите строку: "; cin.getline(string, sizeof(string), '*'); cout << "Вы ввели:\n" << string << endl; … } Строки и символьные массивы Результат работы программы: Аналогичный результат получится при дополнении программы вводом с использованием функции get() с тремя аргументами: cin.get(string, sizeof(string), '*'); Строки и символьные массивы Кроме того, для считывания в строку всех введенных символов из входного потока данных можно воспользоваться функцией стандартной библиотеки ввода/вывода gets() – считывает поток символов в строку до тех пор, пока не будет нажата клавиша ENTER Дополним программу вводом с использованием функции gets(): #include … gets (string); Строки и символьные массивы В данном случае с помощью функции gets() считаются все введённые символы с пробелами до тех пор, пока во вводимом потоке не встретится код клавиши Enter. Строки и символьные массивы Часто при выполнении программы требуется вывести некоторое текстовое сообщение в консоль. Если это сообщение написано на латинице, то в командной строке Windows оно будет отображаться корректно. А если текстовое сообщение написано на кириллице, то вместо передаваемого сообщения, последовательность букв и символов будет отображаться некорректно. Строки и символьные массивы Результат работы предыдущей программы при вводе кириллицей строки «Кто владеет информацией, тот владеет миром» и выводе ее на экран: Строки и символьные массивы Проблема заключается в том, что Microsoft при разработке Windows создали новую кодировку для кириллицы. При этом оставили старую кодировку, которая использовалась в MS DOS. В результате консоль, как часть операционной системы Windows, унаследовала кодировку кириллицы от MS DOS. Таким образом для кириллицы существуют две кодировки: cp866 и cp1251 (она же windows-1251). cp (codepage) – страница кодировки символов. Примечание: стандарт кодирования Unicode не рассматриваем. Строки и символьные массивы Консоль имеет собственную настройку кодовой страницы. По умолчанию в командной строке Windows используется кодировка символов cp866,т.е. в командной строке Windows все символы закодированы по кодировочной таблице cp866. Причем поменять кодировку в командной строке Windows нельзя. А во всех русскоязычных Windows используется стандарт кодирования символов cp1251, который наследуется программой. Строки и символьные массивы В итоге, получается, что программа передает коды символов сообщения стандарта cp1251. Командная строка принимает эти коды и переводит их в символы, но уже по стандарту cp866, так как другого стандарта не знает. Коды кириллицы у этих кодировок разные. В результате сообщение передано в консоль, но символы интерпретированы не правильно, в связи с этим сообщение отображается некорректно. Строки и символьные массивы Для решения данной проблемы необходимо перед тем, как передать текст в консоль, перекодировать его в стандарт кодирования символов cp866. Обратите внимание. Функция setlocale() выполняет перекодировку символов в соответствии с требуемым языком. Однако, данная функция работает только с потоком вывода, при использовании потока ввода она проблему некорректного отображения сообщения не снимает. Строки и символьные массивы Рассмотрим способы перекодировки символов при работе с потоком ввода. Одно из возможных решений – использование функций OemToChar и CharToOem. Данные функции определены в заголовочном файле Функция OemToChar() предназначена для перекодировки введенной ОЕМ строки (кодировка cp866) в набор символов кодировки ANSI (cp1251). Функция CharToOem() выполняет обратное действие. Строки и символьные массивы Прототип функций: BOOL OemToChar(LPCTSTR lpszSrc, LPSTR lpszDs); BOOL CharToOem(LPCTSTR lpszSrc, LPSTR lpszDs); lpszSrc – указатель на преобразуемую строку lpszDs – указатель на строку, в которую будет помещен результат преобразования Однако, данные функции преобразуют лишь одну строку. Если в программе с использованием кириллицы вводится из консоли и выводится несколько строк, то каждую строку надо преобразовывать, т.е., каждый раз при этом надо вызывать функцию OemToChar / CharToOem. Строки и символьные массивы Функции CharToOemBuff и OemToCharBuff работают также как и функции CharToOem / OemToChar, с той лишь разницей, что в качестве третьего параметра принимают количество символов в строке, которые надо преобразовать Прототип функций: BOOL CharToOemBuff(LPCTSTR lpszSrc, LPSTR lpszDst, DWORD cchDstLength); BOOL OemToCharBuff(LPCTSTR lpszSrc, LPTSTR lpszDst,DWORD cchDstLengt); Строки и символьные массивы Дополним программу выводом с использованием функции OemToChar(): … #include … OemToChar(string, string); … Результат работы программы: Строки и символьные массивы Другой вариант решения – использование функций SetConsoleCP и SetConsoleOutputCP. Данные функции определены в заголовочном файле Функция SetConsoleCP() устанавливает нужную кодовую таблицу на поток ввода. Функция SetConsoleOutputCP() устанавливает нужную кодовую таблиц, на поток вывода. В качестве единственного параметра обеим функциям передается номер кодовой страницы. В нашем случае (кириллица) – это 1251. Строки и символьные массивы Прототип функций: BOOL WINAPI SetConsoleCP( _In_ UINT wCodePageID); BOOL WINAPI SetConsoleOutputCP( _In_ UINT wCodePageID); wCodePageID – идентификатор кодовой таблицы Обратите внимание. У данных функций есть один весомый недостаток – они работают со шрифтом Lucida Console. По умолчанию в консоли стоит шрифт Consolas. Поэтому в командной строке необходимо настроить используемый шрифт. Для этого: 1. Запустите командную строку cmd.exe Строки и символьные массивы 2. Откройте контекстное меню. Строки и символьные массивы 3. Зайдите в настройки консоли Строки и символьные массивы 4. Измените шрифт на Lucida Console Строки и символьные массивы 4. Нажмите ОК. Обратите внимание. Если функция SetConsoleOutputCP(1251) выполнена до функции setlocale(LC_ALL,"Rus"), то функция setlocale() на ввод-вывод кириллицы уже не влияет, но может потребоваться для других национальных настроек (разделитель дробной части числа, формат даты, времени и пр.) Строки и символьные массивы Пример программы вывода строки с использованием функций SetConsoleCP и SetConsoleOutputCP: … #include … int main() { SetConsoleCP(1251); // установка кодовой страницы cp1251 в поток ввода SetConsoleOutputCP(1251); // установка кодовой страницы cp1251 в поток вывода char string[100] = ""; cout << "Ваша любимая цитата: "; gets (string); cout << string << endl; … } Строки и символьные массивы Результат работы программы: Строки и символьные массивы Рассмотрим функции для работы со строками и символами библиотеки cstring. Прототип функции strlen(): size_t *strlen(const char *имя_строки); Функция strlen() определяет длину строки имя_строки без учета нуль-терминатора \0. Строки и символьные массивы Пример подсчета символов в строке, вводимой пользователем с клавиатуры … #include int main() { … char string[100] = ""; cout << "Введите текст не более 100 символов\n\n"; gets (string); cout << endl; cout << "Строка \"" << string << "\" состоит из " << strlen(string) << " символов\n"; … } Строки и символьные массивы Результат работы программы: Строки и символьные массивы Копирование строк. Функции strcpy() и strncpy() Прототип функции strcpy(): char *strcpy(char *str1, const char *str2); Функция strcpy() выполняет побайтное копирование символов из строки str2 в строку str1, включая нулевой символ, и возвращает указатель на строку str1. При этом выход за границы массива str1 не контролируется. Строки и символьные массивы Прототип функции strncpy() char *strncpy(char *str1, const char *str2, num); Функция strncpy() выполняет побайтное копирование num символов из строки str2 в строку str1 и возвращает указатель на строку str1. Обратите внимание. В обоих случаях размер первого символьного массива должен быть достаточным для помещения символов второго массива. Иначе запись строки выйдет за пределы памяти, выделенную под первый символьный массив. Строки и символьные массивы Пример копирования одной строки и вставки ее и ее части в другие строки. … #include int main() { … char s1[40] = ""; cout << "Введите текст не более 40 символов: "; gets (s1); cout << endl; char s2[] = "Пример работы функций strcpy и strncpy"; cout << "Строка s1 - \"" << s1 << "\" \n\n"; cout << "Строка s2 - \"" << s2 << "\" \n\n"; strcpy(s1,s2); Строки и символьные массивы cout << "Строка s1 после копирования s2 - \"" << s1 << "\" \n\n"; char s3[7] = ""; cout << "Строка s3 - \"" << s3 << "\" \n\n"; strncpy(s3, s2, 6); cout << "Строка s3 после копирования части s2 - \"" << s3 << "\" \n"; … } Строки и символьные массивы Результат работы программы: Строки и символьные массивы Конкатенация строк. Функции strcat() и strncat() Прототип функции strcat(): char *strcat(char *str1, const char *str2); Функция strcat() конкатенирует (объединяет) строку str2 со строкой str1 и сохраняет результат в строке str1. В конце модифицированной строки str1 функция ставит нулевой символ. Нулевой символ, первоначально завершавший строку str1, замещается первым символом строки str2. Строки и символьные массивы Прототип функции strcat(): char *strncat(char *str1, const char *str2, num); Функция strncat() добавляет num символов строки str2 в конец строки str1 и сохраняет результат в строке str1. В конце модифицированной строки str1 функция ставит нулевой символ. Нулевой символ, первоначально завершавший строку str1, замещается первым символом строки str2. Строки и символьные массивы Пример объединения одной строки с другой и ее частью. … #include int main() { … char s1[40] = "пример работы функций "; char s2[17] = "strcat и strncat"; strcat(s1,s2); cout << "Строка s1 после объединения со строкой s2" << endl << endl; cout << "\"" << s1 << "\" \n\n"; Строки и символьные массивы char s3[19] = "это простой "; strncat(s3, s1, 6); cout << "Строка s3 после объединения с частью s1" << endl << endl; cout << "\"" << s3 << "\" \n"; … } Строки и символьные массивы Результат работы программы: Строки и символьные массивы Обратите внимание. Если длина исходной строки известна заранее, то вместо функции strcat() эффективнее использовать функцию strcpy(), так как строка, к которой осуществляется добавление, не сканируется в поисках завершающего нуль-терминатора. Строки и символьные массивы Сравнение строк. Функции strcmp(), strncmp(), stricmp() и strnicmp(). Прототип функции strcmp(): int *strcmp(const char *str1, const char *str2); Функция strcmp() осуществляет лексикографическое сравнение двух строк, оканчивающихся нулевыми символами, с учетом регистра и возвращает целое число со следующим значением: 0 – если строки идентичны (по символам и их количеству); Строки и символьные массивы >0 – если строка str1 больше строки str2; <0 – если строка str1 меньше строки str2. Т.е. производится посимвольное сравнение строк до обнаружения пары различных символов или до конца одной из строк и возвращается разность кодов первых не совпавших символов или 0. Строки и символьные массивы Прототипы функций strncmp(), stricmp() и strnicmp() : int *strncmp(const char *str1, const char *str2, num); int *stricmp(const char *str1, const char *str2, num); int *strnicmp(const char *str1, const char *str2, num); Строки и символьные массивы Функция strcnmp() осуществляет лексикографическое сравнение num символов из двух строк, оканчивающихся нулевыми символами, с учетом регистра и возвращает целое число со следующим значением: 0 – если строки идентичны (по символам и их количеству); >0 – если строка str1 больше строки str2; <0 – если строка str1 меньше строки str2. Строки и символьные массивы Если в одной из строк имеется меньше, чем num символов, то сравнение прерывается как только встретится первый нулевой символ. Функции stricmp() и strnicmp() аналогичны функциям strcmp() и strncmp() соответственно, за исключением осуществления лексикографического сравнения строк без учета регистра. Строки и символьные массивы Пример сравнения строк. … #include int main() { … char s1[ ] = "strcmp, strncmp"; char s2[ ] = "strcmp, strncmp"; cout << "s1: \"" << s1 << "\"" << endl << endl; cout << "s2: \"" << s2 << "\"" << endl << endl; cout << "s1 == s2 -> " << setw(2) << strcmp(s1,s2) << endl << endl; |