Относительно sizeof(cleaned)
: использование sizeof
для получения емкости массива работает, только если аргумент является массивом, а не указателем:
char buffer[100];
const char *pointer = "something something dark side";
// Prints 100
printf("%zu\n", sizeof(buffer));
// Prints size of pointer itself, usually 4 or 8
printf("%zu\n", sizeof(pointer));
Хотя и локальный массив, и указатель могутбыть подписанным, они ведут себя иначе, когда дело доходит до sizeof
.Таким образом, вы не можете определить емкость массива, учитывая только указатель на него.
Кроме того, имейте это в виду:
void foo(char not_really_an_array[100])
{
// Prints size of pointer!
printf("%zu\n", sizeof(not_really_an_array));
// Compiles, since not_really_an_array is a regular pointer
not_really_an_array++;
}
Хотя not_really_an_array
объявлен как массив, онэто параметр функции, так что на самом деле это указатель.Это точно так же, как:
void foo(char *not_really_an_array)
{
...
Не совсем логично, но мы застряли с этим.
По вашему вопросу.Мне неясно, что вы пытаетесь сделать.Простое удаление первого символа строки (на месте) может быть выполнено с помощью memmove:
memmove( buffer // destination
, buffer + 1 // source
, strlen(buffer) - 1 // number of bytes to copy
);
Это занимает линейное время и предполагает, что buffer
не содержит пустой строки.
Причина, по которой strcpy(buffer, buffer + 1)
не будет работать, состоит в том, что строки перекрываются, поэтому это приводит к неопределенному поведению.memmove
, однако, явно позволяет перекрывать источник и назначение.
Для более сложной фильтрации символов вам следует рассмотреть обход строки вручную, используя указатель «чтение» и указатель «запись».Просто убедитесь, что указатель записи не опережает указатель чтения, поэтому строка не будет засорена во время чтения.
void remove_semicolons(char *buffer)
{
const char *r = buffer;
char *w = buffer;
for (; *r != '\0'; r++)
{
if (*r != ';')
*w++ = *r;
}
*w = 0; // Terminate the string at its new length
}