Вставка символов в середине массива символов - PullRequest
1 голос
/ 15 февраля 2012

У меня есть массив символов, заполненный некоторыми символами. Допустим, у меня есть "HelloWorld" в моем массиве символов. (не строка. Взятие индекса от 0 до 9)

То, что я пытаюсь сделать, это вставить символ в середину массива и сдвинуть остальные в сторону, чтобы освободить место для нового вставляемого символа.

Итак, я могу создать массив char, в котором будет "Hello.World".

char ch[15]; // assume it has "HelloWorld" in it
for(int i=0; i<=strlen(ch)-1; i++) {
    if(ch[i]=='o' && ch[i+1]=='W') {
        for(int j=strlen(ch)-1; j>=i+2; j--) {
            ch[j] = ch[j-1]; // pushing process?
        }
        ch[i+1] = '.';
        break;
    }
}

Будет ли это работать? Был бы более легкий путь? Я мог бы просто думать слишком сложным об этом.

Ответы [ 5 ]

3 голосов
/ 15 февраля 2012

Вам нужно начать внутренний цикл с strlen(ch) + 1, а не strlen(ch) - 1, потому что вам также необходимо переместить NULL-терминатор в нужное место. Помните, что strlen возвращает длину строки, такую ​​что string[strlen(string)] == '\0'; Вы можете думать о strlen как о функции для получения индекса NULL-терминатора C-строки.

2 голосов
/ 15 февраля 2012

Если вы хотите переместить все символы вверх на один, то вы можете сделать это, используя memmove.

#include <string.h>

char ch[15];

int make_room_at = 5;
int room_to_make = 1;

memmove(
    ch + make_room_at + room_to_make,
    ch + make_room_at,
    15 - (make_room_at + room_to_make)
);
1 голос
/ 15 февраля 2012

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

    ch[strlen(ch) + 1] = '\0';
    for(j=strlen(ch); j>=i+2; j--) {  // note no "-1" after the strlen

Редактировать Что касается "Это хороший способ?" часть, я думаю, что это разумно; это просто зависит от намеченной цели. На ум приходит пара мыслей:

  • Сокращение количества вызовов на strlen может быть хорошим. Это может зависеть от того, насколько хорош оптимизатор (возможно, некоторые могут быть оптимизированы). Но каждый вызов strlen требует сканирования строки в поисках нулевого терминатора. В коде с высоким трафиком это может сложиться. Поэтому сохранение начальной длины в переменной и последующее использование переменной в другом месте может помочь.
  • Этот тип операции имеет шанс переполнения буфера. Всегда убедитесь, что буфер достаточно длинный (он находится в OP).
1 голос
/ 15 февраля 2012

Просто сделайте:

#define SHIFT  1
char bla[32] = "HelloWorld";    // We reserve enough room for this example  
char *ptr = bla + 5;            // pointer to "World"    
memmove(ptr + SHIFT, ptr, strlen(ptr) + 1);  // +1 for the trailing null
0 голосов
/ 15 февраля 2012

Если вы собираетесь манипулировать массивом символов, вы не должны делать его статичным.Делая это:

char ch[15];

вы жестко кодируете массив, чтобы в нем всегда было 15 символов.Создание указателя будет шагом 1:

char* ch;

Таким образом, вы можете изменить его по мере необходимости.

...