Всем доброго дня.
Продолжаем изучать строки. Сегодня у нас праздник. Почему?
Да просто мы познакомимся с новым заголовочным файлом – string.h. Нетрудно сообразить, что в нём
описываются стандартные функции, предназначенные для работы со строками. Естественно не следует забывать, что для
использования этих функций необходимо подключить этот заголовочный файл. Я
надеюсь вы не забыли как это делается.
Прочитайте улучшенную версию этого урока "Стандартные функции работы со строками".
В новой версии:
- Ещё более доступное объяснение
- Дополнительные материалы
- 8 задач на программирование с автоматической проверкой решения
Функция strlen().
В практическом задании к прошлому занятию, я просил вас
написать программу, которая вычисляет длину
строки без учета нулевого элемента. Длина
строки - это один из самых важных параметров, характеризующих любую строку, и
необходимый при работе со строками. Для
определения длины строки в заголовочном файле string.h описана
функция strlen().
Данная функция имеет простой синтаксис. Она принимает один
параметр строку символов, и возвращает в результате своей работы целое число - длину
этой строки.
Листинг
15.1
#include <stdio.h>
#include <string.h>
int main(void) {
char str[]="Hello
world";
int n=strlen(str);
printf("Dlina stroki %d simvolov\n",n);
return(0);
}
Рис.1 Программа, иллюстрирующая работу функции strlen(). |
Как видите ничего неожиданного, функция вернула в результате
своей работы число 11.
Теперь, на основании знаний, полученных на прошлом занятии,
объясните результат работы следующей программы.
Листинг
15.2
#include <stdio.h>
#include <string.h>
int main(void) {
char str[100];
fgets(str,100,stdin);
int n=strlen(str);
printf("Dlina stroki %d simvolov\n",n);
return(0); }
Рис.2. Иллюстрация работы программы Листинг 15.2 |
Почему, когда мы ввели Hello world и нажали Enter, наша функция вернула нам число
12, а не 11 как в прошлом случае?
Функции сравнения строк.
Еще одной задачей, предложенной для решения в прошлом
занятии, было написание программы, которая посимвольно сравнивает между собой две
строки. Для выполнения этой операции, тоже
существует готовая функция –strcmp().
Данная функция принимает в качестве аргументов две строки, которые
необходимо сравнить. В результате своей работы, если строки одинаковые, он
возвращает нуль, и если разные, то либо целое число положительное или
отрицательное. Сравнение идет по коду символов в таблице ASCII.
Рассмотрим пример.
Листинг
15.3
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[] = "hello world",
int main(void) {
char str1[] = "hello world",
str2[] = "hello world",
str3[] = "hello
World";
int n12 =
strcmp(str1,str2);
int n13 =
strcmp(str1,str3);
int n31 =
strcmp(str3,str1);
printf(" %s i
%s %d\n", str1, str2,n12);
printf(" %s i
%s %d\n", str1, str3,n13);
printf(" %s i
%s %d\n", str3, str1,n31);
printf("%c/%d\n",str1[6],str1[6]);
printf("%c/%d\n",str3[6],str3[6]);
return(0); }
Результат работы данной программы:
Рис.3. Сравнение строк функцией strcmp() |
Строки str1
и str2 одинаковые и
потому, при их сравнении получилось 0. А вот строки str1 и str3 различаются, регистром символа ‘w’ поэтому результат их
сравнения не равен нулю. Обратите внимание, что в одном случае он равен
единице, а в другом минус единице. Почему так получается, мы сейчас разберемся.
Строки сравниваются посимвольно, использую соответствие
между символом и его кодом в таблице ASCII. Ниже сравнения, в
нашей программе указаны коды символов ‘w’ и ‘W’. Как видите, код символа ‘w’ – 119, больше чем код символа ‘W’ – 87. Значит и строка str1 больше чем строка str3.
Основное правило: Если,
в функции strcmp()
строка записанная в первом аргументе, больше чем строка во втором аргументе, то
функция возвращает положительное число.
Если меньше – отрицательное.
Есть и еще одна функция, предназначенная для сравнения строк
strncmp(). Её отличие
лишь в том, что добавляется третий параметр – целое число, указывающее, сколько
символов с начала строки необходимо сравнить.
Немного преобразуем предыдущую программу
Листинг 15.4
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[] = "hello world",
str2[] = "hello World";
int n1 =
strncmp(str1,str2,6);
int n2 =
strncmp(str1,str2,7);
printf("%s i
%s %d\n", str1, str2,n1);
printf("%s i
%s %d\n", str1, str2,n2);
return(0);
}
Рис.4. Сравнение частей строк, с помощью функции strncmp(). |
Как видите, когда мы сравнили первые шесть символов двух
строк, то получили 0, так как они совпадают. Если же мы сравниваем первые семь
символов, то первая строка больше второй, и в ответе получается положительное
целое число. Причем в данном случае, это разность между кодами соответствующих
символов (119-87 = 32). Пользоваться этим обстоятельством нужно очень осторожно.
Не факт, что в других средах разработки, эти функции реализованы точно таким же
образом. Т.е. может быть, что где-то strcmp будет тоже возвращать 32, а не 1, как в нашем примере. А где-то
возможно strncmp не будет возвращать 32. Как это реализовано в вашей среде
программирования проверьте самостоятельно.
Функции изменения регистра строки.
Как вы помните, в задаче к прошлому уроку требовалось
написать функцию, которая переводит все символы строки в нижний регистр. Для
этой задачи тоже есть готовая функция – strlwr(). Ко всему прочему
имеется и функция, которая переводит все символы в верхний регистр – strupr().
Данные функции принимают один параметр – строку, которую
необходимо перевести в тот или иной регистр. Рассмотрим пример их
использования.
Листинг 15.5
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "HeLLo
WoRlD";
printf ("%s\n",str);
strlwr(str); //переводим строку в нижний регистр
printf ("%s\n",str);
strupr(str); //переводим строку в верхний регистр
printf ("%s\n",str);
return(0);
}
Результат работы программы
Рис.5. Изменение регистра строки функциями strupr() и strlwr(). |
Функции объединения строк.
В файле string.h описаны
две функции для объединения строк.
Первая strcat()
принимает две строки, и приписывает вторую в конец первой. Т.е. результат
склеивания двух строк окажется в той, что записана в первом аргументе. Причем
нулевой символ ‘\0’ добавляется автоматически в конец новой, получившейся
строки. Небольшой иллюстрирующий пример:
Листинг
15.6
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[50] =
"hello",
str2[]="world";
strcat(str1," "); //приклеиваем к str1 пробел получаем
//в str1 строку "hello "
strcat(str1,str2);//приклеиваем к str1 строку str2 printf("%s\n", str1); //выводим str1
return(0);
}
Рис.6. Склеивание двух строк функцией strcat(). |
Вторая функция strncat() отличается от предыдущей, наличием еще одного
аргумента, означающего, какое количество символов с начала второй строки
следует приклеить к первой строке. Немного переделаем наш предыдущий пример.
Листинг 15.7
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[50] =
"hello",
str2[]="world";
strcat(str1," "); //приклеиваем к str1 пробел получаем //в str1 строку "hello "
strncat(str1,str2,3);
//приклеиваем к str1 3 первых //символа из str2
printf("%s\n", str1); //выводим str1
return(0);
}
Ну и соответственно результат её работы.
Рис.7. Использование функции strncat(). |
Ничего удивительного. Все работает именно так, как и
ожидалось.
При работе с этими двумя функциями стоит внимательно следить
за тем, чтобы в строке, к которой мы приклеиваем, хватило места, иначе
произойдет ошибка переполнения. С ней мы уже сталкивались с прошлом занятии.
Вот попробуйте выполнить следующую программу.
Листинг 15.8
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[10] =
"hello",
str2[]=" world";
strcat(str1,str2);
printf("%s\n", str1);
return(0);
}
Хотя программа и скомпилируется, но при выполнении возникнет
ошибка.
На этом сегодняшний урок мы закончим. Мы рассмотрели лишь
некоторые функции, описанные в заголовочном файле string.h. Есть там еще несколько очень
интересных и полезных функций, но о них мы поговорим чуть позже, когда
познакомимся с указателями.
Отдельного практического задания к этому уроку не будет. Проверьте с помощью стандартных функций
программы, написанные к прошлому занятию. А 3,4 и 5 задачи перепишите с
использованием стандартных функций.
Если Вам понравился этот урок, расскажите о нем вашим друзьям. В этом Вам могут помочь кнопки основных социальных сетей, расположенные ниже. Вам остается всего лишь кликнуть по любой из них.
решал задачку с перевёртышами из прошлого урока. возник вопрос
ОтветитьУдалить#include "stdio.h"
#include "string.h"
int main(void) {
char str1[100],str2[100];
fgets(str1,100,stdin);
strlwr(str1);
str2[100]=str1[100];
printf("%s\n", str2);
return(0);
}
почему при выводе показателя str2, который я до этого приравнял к str1, появляется "мусор"?
Потому что, вот так просто нельзя копировать строки, к сожалению. =))) Тут нужно либо посимвольно с использование цикла, либо специальными функциями пользоваться.
УдалитьВ листинге 15.5 комментарии поменять местами надо)
ОтветитьУдалитьИ действительно. Спасибо за бдительность! )
УдалитьА мне программа из листинга 15.2 при вводе Hellow World выдает -1098753604. Это норма?
ОтветитьУдалитьПереписывал задание 5 прошлого урока при помощи изученных функций. Возник вопрос, почему ответ выводится не на экран а в файл "in.txt" и почему выводит ответ, что строка состоит из 0 символов.
ОтветитьУдалить#define _CRT_SECURE_NO_WARNINGS
#include
#include
char fun1(char arr[]);
int main(void)
{
char str1[200];
fun1(str1);
char mass[28] = { 0 }, c = 0;
freopen("D:\\in.txt", "r", stdin);
while (c = getchar())
{
if (c == EOF) break;
mass[27]++;
if (c == 32) mass[26]++;
if (c > 96 && c < 123) mass[c - 97]++;
}
printf("dlina stroki - %d\n", mass[27]);
printf("kolichestvo probelov - %d\n", mass[26]);
for (int i=0; i < 26; i++)
if (mass[i] > 0) printf("%c - %d\n", i + 97, mass[i]);
return(0);
}
char fun1(char arr[])
{
freopen("D:\\input.txt", "r", stdin);
gets(arr);
freopen("D:\\in.txt", "w", stdout);
_strlwr(arr);
puts(arr);
return (0);
}
в последнем я так понял ошибка вылезет потому что str1[10], это при том что символов выйдет 11. думаю я прав, компилировать правда не стану
ОтветитьУдалитьОчень понятно написано!
ОтветитьУдалитьСпасибо!
Пожалуйста. В новой версии сайта youngcoder.ru всё ещё понятнее. Заходите.
Удалить