Определение длины строки – функция strlen()

Функция strlen() определяет длину строки.

 

puts("Enter a string: ");

gets(myString);

printf("Length = %d\n", strlen(myString));

 

 

char myString[40];

puts("Введите строку: ");

gets(myString);

puts("\nСтрока наоборот:");

for (int i=strlen(myString)-1; i>=0; i--) {

putchar(myString[i]);

}

 

      Присвоение (копирование строк) – функция strcpy()

           char string1[] = "Привет";

char string2[30];

puts("Строка1 =");

puts(string1);

 

strcpy(string2, string1);

puts("Теперь строка2 =");

puts(string2);

      Объединение двух строк – функция strcat()

char full_name[50];

char first_name[30];

char second_name[30];

 

puts("Введите имя: ");

gets(first_name);

puts("Введите фамилию: ");

gets(second_name);

 

//Вначале строка пустая

strcpy(full_name, "");

//Присоединяем имя

strcat(full_name, first_name);

//Присоединяем пробел

strcat(full_name, " ");

//Присоединяем фамилию

strcat(full_name, second_name);

 

puts("Полное имя:");

puts(full_name);

 

      Сравнение строк в алфавитном порядке – функция strcmp()

      Проверка наличия символа в строке – функция strchr()

 

char word[40];

char letter;

puts("Введите слово:");

gets(word);

puts("Введите букву:");

letter = getchar();

if (strchr(word, letter)!= NULL) {

   puts("Буква есть в слове.");

} else {

   puts("Буквы нет в слове.");

}

 

 

 

6.Как передавать строки в качестве аргументов функций? Приведите пример.

 

Строки – это массивы символов, поэтому они передаются в функции так же, как и массивы. Отличие заключается в том, что передавать длину строки не нужно, так как строки заканчиваются нуль-символом, благодаря которому конец строки или ее длину можно определить.

Рассмотрим этот механизм на примере. Напишем функцию, которая принимает в качестве аргумента строку и возвращает количество цифр в этой строке. Под цифрой будем понимать один из символов от ‘0’ до ‘9’. Алгоритм этой функции достаточно прост: нужно объявить переменную, которую инициализировать нулем, и пробежаться по всей строке, символ за символом, инкрементируя эту переменную, если символ является цифрой. Как определить, является ли символ цифрой? Перед ответом на этот вопрос заметим, что данную проверку будет разумно вынести в отдельную функцию, назовем ее isDigit(), которая принимает строку и возвращает true или false в зависимости от результата проверки. Согласно кодировке символы, отвечающие за цифры, идут один за другим. Проверьте это, выведя значения этих символов с помощью спецификатора целого числа:

const char digits[] = "0123456789";

printf("-----------------------\n");

printf("|%6s %3s|", "Символ", "Код");

printf("%6s %3s|\n", "Символ", "Код");

printf("-----------------------\n");

for (int i=0; i<strlen(digits); i+=2) {

char dgt = digits[i];

printf("| \'%c\' %-3d|", dgt, dgt);

dgt = digits[i+1];

printf(" \'%c\' %-3d|\n", dgt, dgt);

 

}

printf("-----------------------\n");   

 

Используя это наблюдение, функцию isDigit() можно реализовать следующим образом:

 

bool isDigit(char symbol) {

return '0'<=symbol && symbol<='9';

}

 

Записи '0'<=symbol и symbol<='9' подразумевают, что символы заменяются на их числовые значения согласно установленной кодировке, а затем производится сравнение.

Желающие действовать «в лоб» могут довольствоваться другой реализацией:

 

bool isDigitV2(char symbol) {

const char digits[] = "0123456789";

for (int i=0; i<strlen(digits); i++) {

if (symbol==digits[i]) {

   return true;

}

}

return false;

}

 

Используя реализованную функцию проверки, является ли символ цифрой, функция подсчета количества цифр в строке принимает лаконичный и понятный вид:

 

int getNumberOfDigits(char symbols[]) {

int n_digits=0;

for (int i=0; i<strlen(symbols); i++) {

if (isDigit(symbols[i])) {

   n_digits++;

}

}

return n_digits;

}

 

 

7.Почему передавать длину строки в функцию вместе с самой строкой не нужно?

 

Обратите внимание на то, что поскольку функция isDigit() возвращает значение логического типа, то в условии сравнений уже не нужно. Вызвать написанную функцию можно так:

char str[50];

printf("Введите строку:\n");

gets(str);

printf("Количество цифр равно %d\n",

  getNumberOfDigits(str));

 

8.Как передавать массивы строк в качестве аргументов функций? Приведите пример.

 

Массив строк – это двумерный массив типа char, поэтому передать массив строк в качестве аргумента функции можно так же, как и матрицу. Необходимо указать второй размер, а первый можно указывать, а можно не указывать. Поскольку первый размер по нуль-символу не передается, то количество строк необходимо передать вторым аргументом. Продемонстрируем эту идею на примере. Напишем функцию, которая принимает массив строк и количество строк в этом массиве, и выводит на экран все строки, которые начинаются с заглавной буквы. Для реализации этой функции напишем две вспомогательные, первая из которых проверяет, является ли буква заглавной, а вторая проверяет, начинается ли фраза с заглавной буквы. Здесь мы воспользуемся уже рассмотренным ранее приемом: буквы, идущие подряд, имеют последовательные номера в кодировке.

 

bool isUpper(char letter) {

bool upperEng = 'A'<=letter && letter<='Z';

bool upperRus = 'А'<=letter && letter<='Я';

return upperEng || upperRus;

}

 

bool isFirstUpper(char phrase[]) {

return isUpper(phrase[0]);

}

 

int firstUpper(char phrases[][20], int size) {

int n_uppers=0;

for (int i=0; i<size; i++) {

if (isFirstUpper(phrases[i])) {

n_uppers++;

}

}

return n_uppers;

}

 

 

9.Какие особенности нужно учитывать при сортировке массива строк?

Задача сортировки массива строк аналогична задаче сортировки числового массива, и все алгоритмы сортировки чисел могут быть применены для сортировки строк. Разница заключается только в деталях реализации этих алгоритмов. Две основные операции, которые используются в сортировке – это сравнение элементов и перестановка элементов. При сравнении чисел, если выполняется неравенство a>b, то мы говорим, что число a «больше» числа b. Самым распространенным вариантом сравнения строк является алфавитный или более общий лексико-графический порядок. Он задается функцией strcmp(), поэтому при сравнении строк вместо If (Str1<str2)

Нужно писать

If (Strcmp(str1,str2)<0)

Если нужно отсортировать строки по длине, то следует записать так:

If (strlen(str1)<strlen(str2))

Перестановка двух строк также специфична. Поскольку строка представляет собой массив, то шаблон перестановки для чисел не подойдет.

Str1=str2

Необходимо использовать функцию strcpy()

Strcpy(str1,str2)

Следующая программа демонстрирует сортировку строк (жирным шрифтом выделена собственно сортировка):   

 

#define N 8

 

char names[N][20] = {

"Сергей", "Мария", "Василий", "Дмитрий",

"Татьяна", "Виталий", "Артем", "Елена"

};

 

void printNames() {

for (int i=0; i<N; i++) {

puts(names[i]);

}

}

 

void sortNames() {

for (int i=1; i<N; i++) {

for (int j=0; j<N-1; j++) {

if (strcmp(names[j],names[j+1]) > 0) {

   char temp[20];

   strcpy(temp, names[j]);

   strcpy(names[j], names[j+1]);

   strcpy(names[j+1], temp);

}

}

}

}

 

int main() {

puts("До сортировки:");

printNames();

puts("\nПосле сортировки:");

sortNames();

printNames();

}

 

 

Если в данном коде изменить условие, поставив вместо

if (strcmp(names[j],names[j+1]) > 0) {

}

 

условие

if (strlen(names[j])<strlen(names[j+1])) {

}

 

то строки будут отсортированы по длине:     

 

 

10.Как можно реализовать динамический выбор (в момент исполнения программы) порядка сортировки, не меняя алгоритма сортировки? Привести пример.

 

Порядок сортировки может быть разным. В предыдущем примере сортировка осуществлялась либо в алфавитном порядке, либо согласно длине. В алфавитном порядке отсортировать также можно двумя способами: по возрастанию и по убыванию. Если же мы будем работать не с массивом строк или чисел, а с массивом записей, каждая из которых состоит из нескольких полей, то типов сортировки может быть еще больше. Вопрос заключается в следующем: «Для каждой сортировки нужно писать свою функцию, или, все-таки, можно обойтись одной?»

В рассмотренном выше примере сортировка по алфавиту и сортировка по длине отличается лишь условием, поэтому неразумно делать две функции, которые почти одинаковы. Хорошим решением является передача типа сортировки в качестве аргумента. Но какого? Однозначного ответа нет, поскольку вариантов сортировки может быть много, поэтому давайте положим, что требуется реализовать сортировку либо по возрастанию, либо по убыванию. Для этого сойдет параметр логического типа, который принимает значение true, если требуется обратный порядок, и false – прямой. Чтобы не было путаницы эти значения лучше задать именованными константами REVERSE_ORDER и STRAIGHT_ORDER.

Ниже приведена программа, которая определяет порядок сортировки массива согласно выбору в меню.

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

//Размер списка

#define N_CITIES 12

//Максимальная длина названия

#define MAX_LENGTH 15

//Обратный порядок сортировки

#define REVERSE_ORDER true

//Прямой порядок сортировки

#define STRAIGHT_ORDER false

 

//Список городов

char cities[N_CITIES][MAX_LENGTH] = {

"Новосибирск", "Москва", "Цюрих",

"Нью Йорк",  "Мадрид", "Париж",

"Барселона", "Лондон", "Токио",

"Монте-Карло", "Глазго", "Каир"

};

 

//Прототипы используемых функций

void printCities();

void sortCities(bool order);

void printMenu();

int getChoice();

 

int main() {

while (true) {

printMenu();

switch(getChoice()) {

case 1:

   sortCities(STRAIGHT_ORDER);

   printCities();

   break;

case 2:

   sortCities(REVERSE_ORDER);

   printCities();

   break;

case 0:

   exit(EXIT_SUCCESS);

default:

   exit(EXIT_FAILURE);

}

//Подождать, пока пользователь

//нажмет любую клавишу

system("pause");

}

return 0;

}

 

//Вывод списка городов

void printCities() {

for (int i=0; i<N_CITIES; i++) {

puts(cities[i]);

}

}

 

//Сортировка списка городов

//(метод прямого выбора)

//Аргумент order может равняться

//STRAIGHT_ORDER или REVERSE_ORDER

void sortCities(bool order) {

for (int i=0; i<N_CITIES-1; i++) {

int min=i;

for (int j=i+1; j<N_CITIES; j++) {

if (order ^

     strcmp(cities[min], cities[j])>0) {

   min=j;

}

}

char temp[MAX_LENGTH];

strcpy(temp, cities[min]);

strcpy(cities[min], cities[i]);

strcpy(cities[i], temp);

}

}

 

//Вывод меню на экран

void printMenu() {

//Очистка экрана   

system("cls");

printf("---МЕНЮ---\n");

printf("1-Прямой порядок\n");

printf("2-Обратный порядок\n");

printf("0-Выход\n");

printf("Ваш выбор - ");

}

 

//Выбор пункта меню и

//проверка его правильности (0, 1 или 2)

int getChoice() {

int choice;

scanf("%d", &choice);

if (choice<0 || choice>2) {

printf("Нет такого пункта\n");

printf("Выберите еще раз - ");

//Если выбор неверный,

//то предлагаем попробовать еще раз

return getChoice();

}

return choice;

}

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: