Выбрать главу

Функция strcat( )

Вот что умеет делать функция strcat( ):

/* объединение двух строк */

#include

< stdio.h>

main( )

{

static char flower [80];

static char addon[  ] = "ы пахнут старыми ботинками.";

puts(" Назовите ваш любимый цветок." );

gets(flower);

strcat (flower, addon);

puts(flower);

puts(addon);

}

Получаем на экране:

Назовите ваш любимый цветок.

Ирис

Ирисы пахнут старыми ботинками.

    Очевидно, что strcat( ) (string concatenation) использует в качестве аргументов две строки. Копия второй строки присоединяется к концу первой, и это объединение становится новой первой строкой. Вторая строка не изменяется.

     Внимание! Эта функция не проверяет, умещается ли вторая строка в первом массиве. Если вы ошиблись при выделении памяти для первого массива, то у вас возникнут проблемы. Конечно, можно использовать strlen( ) для определения размера строки до объединения.

/* Объединение двух строк, проверка размера первой */

#include <stdio.h>

#define SIZE 80

main( )

{

static char flower[SIZE];

static char addon[ ] = " ы пахнут старыми ботинками." ;

puts(" Назовите ваш любимый цветок. ");

gets(flower);

if((strlen(addon) + strlen(flower) + 1) < SIZE)

    strcat (flower, addon);

puts(flower);

}

Мы добавляем 1 к объединенной длине для размещения нуль-символа.

Функция strcmp( )

     Предположим, что вы хотите сравнить чей-то ответ со строкой, находящейся в памяти:

/* Будет ли это работать? */

#include <stdio.h>

#define ANSWER  " Грант"

main( )

{

char try [40];

puts(" Кто похоронен в могиле Гранта?" );

gets(try);

while(try != ANSWER)

puts(" Нет, неверно. Попытайтесь еще раз." );

gets(try);

} puts(" Правильно.");

}

     Хотя эта программа и смотрится неплохо, она не будет работать правильно, try и ANSWER на самом деле являются указателями, поэтому сравнение (try != ANSWER) спрашивает не о том, одинаковы ли эти две строки, а одинаковы ли два адреса, на которые ссылаются try и ANSWER. Так как ANSWER и try запоминаются в разных ячейках, эти два указателя никогда не могут быть одним и тем же, и пользователю всегда сообщается, что программа неверна. Такие программы обескураживают людей.

     Нам нужна функция, которая сравнивает содержимое строк, а не их адреса. Можно было бы придумать ее, но это уже сделала за нас функция strcmp( ) (string comparision).

Теперь исправим нашу программу:

/* это будет работать */

#includе <stdio.h>

#define ANSWER " Грант"

main( )

{

char try [40];

puts(" Кто похоронен в могиле Гранта?" );

gets(try);

while(strcmp(try, ANSWER) != 0)

{ puts(" Нет, неверно. Попытайтесь еще раз.");

gets(try);

} puts(" Правильно!");

}

     Так как ненулевые значения интерпретируются всегда как "true", мы можем сократить оператор while do while(strcmp(try, ANSWER)).

     Из этого примера можно сделать вывод, что strcmp( ) использует два указателя строк в качестве аргументов и возвращает значение 0, если эти две строки одинаковы. Прекрасно, если вы придете к такому выводу.

     Хорошо, что Strcmp( ) сравнивает строки, а не массивы. Поэтому, хотя массив try занимает 40 ячеек памяти, а " Грант" - только 6 (не забывайте, что одна нужна для нуль-символа), сравнение выполняется только с частью try, до его первого нуль-символа. Такую функцию strcmp( ) можно использовать для сравнения строк, находящихся в массивах разной длины.

     А что если пользователь ответил " ГРАНТ" или " грант" или "Улиссес С. Грант" ? Хорошо, если пользователю сказали, что он ошибся? Чтобы сделать программу гибкой, вы должны предусмотреть несколько допустимых правильных ответов. Здесь есть некоторые тонкости. Вы могли бы в операторе #define определить в качестве ответа " ГРАНТ" и написать функцию, которая превращает любой ответ только в это слово. Это устраняет проблему накопления, но остаются другие поводы для беспокойства.

     Между прочим, какое значение возвращает strcmp( ), если строки не одинаковы? Вот пример:

/* возвраты функции strcmp */

#include <a: stdio.h>

main( )

{

printf(" %d \n" , strcmp( "A" , " A" ));

printf(" %d \n" , strcmp( "A" , " B" ));

printf(" %d \n" , strcmp( "B" , " A" ));

printf(" %d \n" , strcmp( "C" , "A" ));

printf(" %d \n" , strcmp(" apples", " apple"));

}

В результате получаем

0 -1

1

2 115

Как мы и предполагали, сравнение "А" с самим собой возвращает 0. Сравнение "А" с "В" дает -1, а "В" с "А" дает 1. Это наводит на мысль, что strcmp( ) возвращает отрицательное число, если первая строка предшествует второй в алфавитном порядке, или положительное число, если порядок иной. Кроме того, сравнение "С" с "А" дает 2 вместо 1. Картина проясняется: функция возвращает разницу между двумя символами в коде ASCII. В более общем смысле strcmp() передвигается вдоль строк до тех пор, пока не находит первую пару не совпадающих символов; затем она возвращает разницу в кодах ASCII. Например, в самом последнем примере "apples" и "apple" совпадают, кроме последнего символа 's', в первой строке. Он сопоставляется с шестым символом в "apple", который является нуль-символом (0 в ASCII).