C функция strcpy () случайным образом меняет один символ - PullRequest
2 голосов
/ 23 марта 2020

Я изучаю строковые функции в C, и я не могу получить демонстрацию моего учителя, используя strcpy(), чтобы удалить пробелы для работы на моей машине, пока он отлично работает для него. Вот исходный код:

#include <stdio.h>
#include <string.h>

int main()
{
    char s[20]="abc   def   ghi";
    char *ptr = strstr(s, "  ");
    while(ptr!=NULL)
    {
        printf("Before trim: %s\n", s);
        strcpy(ptr, ptr+1);
        printf("After trim : %s\n", s);
        printf("\n");
        ptr = strstr(s, "  ");
    }
    return 0;
}

Ожидаемый результат:

Before trim: abc   def   ghi
After trim : abc  def   ghi

Before trim: abc  def   ghi
After trim : abc def   ghi

Before trim: abc def   ghi
After trim : abc def  ghi

Before trim: abc def  ghi
After trim : abc def ghi

Фактический результат:

Before trim: abc   def   ghi
After trim : abc  def   ghi

Before trim: abc  def   ghi
After trim : abc def   ghi

Before trim: abc def   ghi
After trim : abc def  hhi

Before trim: abc def  hhi
After trim : abc def hii

Я искал эту ошибку и узнал, что strcpy() небезопасно, поскольку может вызвать переполнение или неопределенное поведение. Большая часть поиска, который я прочитал, касается буфера назначения, недостаточно велика. Я не знаю ключевое слово этого странного поведения. Может кто-нибудь объяснить мне, что я делаю не так? Заранее спасибо!

1 Ответ

1 голос
/ 23 марта 2020
char *strcpy( char *restrict dest, const char *restrict src ); //(since C99)

Копирует байтовую строку с нулевым символом в конце, на которую указывает src, включая нулевой терминатор, в массив символов, на первый элемент которого указывает dest.

. Поведение не определено , если массив dest недостаточно велик. Поведение не определено, если строки перекрываются . Поведение не определено, если либо dest не является указателем на массив символов, либо src не является указателем на завершенную нулем байтовую строку.

https://devdocs.io/c/string/byte/strcpy

Это то, с чем учитель должен быть осторожен, хотя я должен сказать, что при компиляции кода с несколькими версиями MSV C, clang и g cc мне так и не удалось воспроизвести описанный фактический результат.

...