Символьные массивы в языке С. Работа со строками
Задание 5
- Произведите последовательное изменение букв во второй строке: каждую строчную букву замените прописной, записывая при этом оставшиеся буквы строчными. Проанализируйте результат выполнения программы.
- Протестируйте программу при изменении длины одной из строк, т.е. когда в одной строке не писать запятую.
- Внесите изменения в программу для совпадения двух строк.
- В символьный массив добавьте еще одну строку. Произведите сравнение между собой всех трех строк массива.
- Напишите программу по выводу на консоль информации о человеке с помощью пароля, который вводится с клавиатуры. Информация должна содержать имя, фамилию, год, месяц и число рождения, место рождения. В качестве пароля возьмите свою фамилию с учетом регистра (т.е. прописные или строчные буквы).
Пример 6. Напишите программу создания символьного трехмерного массива, когда, например, на одной странице имеются три строки и на второй странице имеются также три строки. Предусмотрите изменение регистра в выводе на экран строк, когда строчные буквы становятся прописными и наоборот.
Для перевода регистра используем библиотечные функции tolower() и toupper() с подключением библиотеки <ctype.h>.
Программный код решения примера:
#include <stdio.h> #include <conio.h> #include <string.h> #include <ctype.h> #define n 3 #define m 2 #define N 79 int main (void) { int i, k; // Определение и инициализация символьного массива char str[n][m][N] = { {"department: fet", "Specialization: acouY"}, {"Course: 1st", "SURNAME: ivAnov"}, {"Group: 141", "nAmE: Peter"} }; // Построчный вывод 1-й страницы printf("\n\t 1?st page:\n"); for (i = 0; i < n; ++i){ printf("\t"); printf("%s\n", str[i]); } // Посимвольный вывод 2-й страницы printf("\n\t 2?nd page:\n"); for (i = 0; i < n; ++i) { printf("\t"); for (k = 0; k < N; ++k) printf("%c", toupper(str[i][m-1][k])); // или tolower() } printf("\n\n Press any key: "); _getch(); return 0; }
В программе используется трехмерный массив размера 3 2 80. Это означает, что прямоугольная таблица (массив) данных размера 3 80 как бы скрепляется 2 раза, например, по заданному числу страниц. Следует обратить внимание на вывод страниц. В первом случае используется построчный вывод со спецификатором %s, а во втором – посимвольный вывод со спецификатором %c. Кроме того, в первом случае к заданному массиву обращение происходит только по одной размерности, а во втором – используются все три размерности массива. Третий размер – число 80 – взят для того, чтобы строки умещались на всей ширине дисплея.
Результат выполнения программы показан на рис. 6.6.
Задание 6
- Примените функцию tolower() для перевода в строчные буквы.
- Для построчного вывода 1-й страницы используйте две размерности заданного массива.
- В программу добавьте нумерацию строк, например, 1), 2), 3).
- Предусмотрите вывод всей первой страницы, а для второй страницы – только 1-ю и 3-ю строки.
- Напишите программу с обработкой трехмерного символьного массива размера 2 3 80.
- Сделайте вывод строк с заглавными первыми буквами.
Пример 7. В символьной строке находятся слова и два числа, разделенные пробелами или запятыми. Выделите из строки слова и числа, разместите их в отдельных массивах. При этом считанные числа и слова разместите в дополнительных символьных массивах. Выведите значения сформированных символьных массивов. Произведите преобразование строковых (символьных) чисел к числам с плавающей точкой (тип double ). Если после десятичной точки находится нуль (или нули), то число определите как целое, в противном случае – как число с плавающей точкой, т.е. типа double.
Для решения примера используем библиотечные функции isalpfa() для определения буквы во входном потоке (с подключением библиотеки ctype.h ), isspace() – для определения пробелов во входном потоке (с подключением библиотеки ctype.h ), isdigit() – для определения цифры во входном потоке (с подключением библиотеки ctype.h ), atof() – для преобразования строки чисел в число с плавающей точкой (с подключением библиотеки stdlib.h ), atoi() – для преобразования строки чисел в целое число (с подключением библиотеки stdlib.h ), modf() – для выделения целой и дробной части числа (с подключением библиотеки math.h ), strlen() – для определения длины строки (с подключением библиотеки string.h ).
Программный код решения примера:
#include <stdio.h> #include <conio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <math.h> #define N 79 int main (void) { double r = 0.0, b3, b4; int i, j, k, m, n, A[N], n2, n3, n4; char str[N], str2[N], str3[N], str4[N]; // Множественная инициализация i = j = k = m = 0; // Обнуление символьных массивов for (n2 = 0; n2 < N; ++n2) str2[n2] = 0; for (n3 = 0; n3 < N; ++n3) str3[n3] = 0; for (n4 = 0; n4 < N; ++n4) str4[n4] = 0; printf("\n\t Print line with 2-nd numbers:\n\t "); gets_s(str, sizeof(str)/sizeof(str[0])); printf("\n\t The line is:\n"); printf("\t %s\n", str); while (str[i] != '\0') { if ( isalpha(str[i]) || isspace(str[i]) ) str2[j++] = str[i]; else if (isdigit(str[i]) || str[i] == '.') A[k++] = i; // массив индексов цифр потока else str2[j++] = str[i]; ++i; } printf("\n\t A string of words and symbols:\n\t"); puts(str2); if (k > 0) { n = 0; for (i = 0; i < k; ++i){ if (A[i + 1] - A[i] == 1 ) str3[n++] = str[A[i]]; else if (A[i+1] - A[i] > 1) {m = A[i+1]; str3[n++] = str[A[i]]; break;} } } printf("\n"); if (n > 0) { r = modf(atof(str3), &b3); if (!r) // если не нуль printf("\t The number is an integer: %d", atoi(str3)); else printf("\t The number is real (double): %lf\n", atof(str3)); } if (m > 0 ) { j = 0; for (i = m; i <= A[k - 1]; ++i) str4[j++] = str[i]; r = modf(atof(str4), &b4); if (!r) // если не нуль printf("\t The number is an integer: %d", atoi(str4)); else printf("\t The number is real (double): %lf\n", atof(str4)); } printf("\n\n Press any key: "); _getch(); return 0; }
В программе функция modf() возвращает величину дробной части числа (переменная r ) и целой части (от переменных b3, b4 взяты их адреса, т.е. &b3, &b4 ). Анализ массива с индексами цифр исходного символьного массива дает возможность выделить индексацию двух чисел входного потока. Функция gets_s() автоматически добавляет символ конца строки '\0', поэтому при объявлении размерности символьного массива следует предусмотреть одно место для '\0'. Для переносимости программ размерность массива в функции gets_s() определена с помощью функции sizeof().
Возможный результат выполнения программы показан на рис. 6.7.