2009-11-14 2 views
0

Я написал эту функцию:Как заменить пробелы и вкладки ничем в C?

void r_tabs_spaces(char *input) { 
     int i; 
     for (i = 0; i < strlen(input); i++) 
     { 
     if (input[i] == ' ' || input[i] == '\t') 
        input[i] = ''; 
     } 
} 

Однако, когда я компилирую это и запустить его, компилятор жалуется, что «ошибка: пустой символ постоянной» в строке, где я пытаюсь ввести [я] = «»;

Как я могу это сделать в C тогда?

+0

Per OP в ниже, этот вопрос является точной копией http://stackoverflow.com/questions/122616/painless-way- to-trim-leading-trailing-whitespace-in-c –

+0

Наткнулся на это сообщение и не мог не заметить, что «замена ничем» не отличается от удаления. :) – Arjan

ответ

8

В C строка представляет собой массив байтов. Вы не можете назначить «пустой байт», но вам придется сдвинуть оставшуюся часть байтов вперед.

Вот один из способов, как это сделать:

char *write = str, *read = str; 
do { 
    // Skip space and tab 
    if (*read != ' ' && *read != '\t') 
     *(write++) = *read; 
} while (*(read++)); 

Помните, что символьные строки в C обычно находятся в памяти, защищенной от записи, поэтому вы должны скопировать в кучу, прежде чем вы можете изменить их. Например, это обычно ошибку сегментации:

char *str = "hello world!"; // Literal string 
str[0] = 'H'; // Segfault 

Вы можете скопировать строку в куче с strdup (среди прочих):

char *str = strdup("hello world!"); // Copy string to heap 
str[0] = 'H'; // Works 

EDIT: На Ваш комментарий, вы можете пропустить только начальный пробел, помня тот факт, что вы видели символ без пробелов. Например:

char *write = str, *read = str; 
do { 
    // Skip space and tab if we haven't copied anything yet 
    if (write != str || (*read != ' ' && *read != '\t')) {  
     *(write++) = *read; 
    } 
} while (*(read++)); 
+0

... и не забывайте заботиться о оставшихся байтах хвоста. Если они распределены динамически, отпустите их. – Dmitry

+0

О, я забыл добавить одну вещь. Мне нужно удалить только ведущие пробелы и вкладки, но если строка содержит их между символами, мне нужно оставить их такими, какими они есть. Они выше решения работают отлично, но они удаляют все из них. Как я могу оставить те, которые находятся между персонажами? – goe

+0

Не забывайте, что '' определяет полезные макросы, а break может выйти из цикла раньше. –

0

Способ удаления символа строки - переместить остальную часть строки на один символ назад.

1

Если у вас есть указатель на строку

"   string with leading spaces" 
^ pointer 

просто переместить его ...

"   string with leading spaces" 
      ^pointer 

, например:

#include <ctype.h> 
/* ... */ 
char mystring[] = "   string with leading spaces"; 
char *pointer = mystring; 
while (*pointer && isspace((unsigned char)*pointer)) ++pointer; 
/* pointer now points to a (possibly empty) string with no leading spaces */ 
+0

+1 Даже не требует, чтобы строка была в куче :) – Andomar

0

Использование

foo += strspn(foo, " \t"); 

для перемещения указателя foo к первому символу, который не является пробелом или вкладкой.

Чтобы действительно удалить символы из динамически выделяемой строки, используйте

size_t offset = strspn(foo, " \t"); 
size_t size = strlen(foo + offset) + 1; 
foo = realloc(memmove(foo, foo + offset, size), size); 
комментарий
Смежные вопросы