Strncpy ( s2, s1, 2 ); // скопировать 2 символа из s1 в s2

puts (s2); // ошибка! нет последнего '\0'

s2[2] = '\0'; // добавляем символ окончания строки

Puts (s2); // вывод

}

Проблемы при копировании строк

При копировании стандартные функции strcpy и strncpy поступают так: определяют

количество символов, которые надо скопировать и затем переписывают их, начиная с первого символа до последнего. Если области источника и приемника не перекрываются, то все проходит нормально. Но попробуем «раздвинуть» строку, например для того, чтобы вставить что-то в ее середину. Пусть в строке s1 записано имя и фамилия человека, а в строке s2 – его отчество.Надо получить в строке s1 полностью имя, фамилию и отчество.

#include <stdio.h>

#include <string.h>

Main()

{

int n;

char s1[80] = "Иван Рождественский",

s2[] = "Петрович ";

n = strlen(s2); // длина второй строки

strcpy (s1+5, s1+5+n); // пытаемся раздвинуть на n символов

strncpy(s1+5, s2, n); // вставляем отчество в середину

puts (s1);

}

При первом вызове strcpy мы хотели скопировать конец строки, начиная с символа с номером 5 (он шестой с начала, так как нумерация идет с нуля) вправо на n символов (объявленная__длина массива символов – 80 – позволяет это сделать). Однако из-за того, что копирование выполнялось с начала блока данных, скопировав на новое место первый символ фамилии ('Р') функция стерла букву 'н' (справа на 9 символов) и т.д. В результате получили

s1 = "Иван РождествеРождествеРождес"

В следующей строчке мы скопировали в середину отчество (без завершающего нуля) и получили

s1 = "Иван Петрович РождествеРождес"

Таким образом, вся задумка не удалась из-за того, что функция копирования работает в данном случае неверно. Выход из этой ситуации такой – написать свою функцию копирования, которая копирует не с начала блока, а с конца (однако она будет неверно работать в обратной ситуации– при сжатии строки). Например, так:

void strcpy1 (char s1[], char s2[])

{

int n = strlen(s2);

while (n >= 0)

{

s1[n] = s2[n];

n --;

}

}

Заметьте, что завершающий нуль строки s2 также копируется. Если использовать в нашем

примере эту функцию вместо strcpy, то получим желаемый результат.

Возникает вопрос: можно ли сделать функцию, которая всегда правильно копирует? Конечно, можно, хотя это и не просто. Для этого в самой функции надо использовать вспомогательную строку (ее называют буфером) и в ней формировать результат так, чтобы в процессе копирования не портилась исходная строка. Когда результат в буфере готов, его останется скопировать в то место, где была исходная строка и удалить память, выделенную под буфер. Попробуйте написать такую функцию, если известно, что ее будут использовать для копирования строк длиной не более 80 символов.

Объединение строк

Еще одна функция – strcat (от str ing con cat enation – сцепка строк) позволяет добавить

строку источник в конец строки-приемника (завершающий нуль записывается автоматически).

Надо только помнить, что приемник должен иметь достаточный размер, чтобы вместить обе исходных строки. Функция strcat автоматически добавляет в конец строки-результата завершающий символ '\0'.

#include <stdio.h>

#include <string.h>

Main()

{

char s1[80] = "Могу, ",

s2[] = "хочу, ", s3[] = "надо!";


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



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