
Другие языки программирования и технологии
Удалить знаки пунктуации из строки. Язык Си.
Подскажите с функцией. Как перезаписать строку?


Вообще, в Си есть заголовочный файл ctype.h, в котором объявлена функция, определяющая, что определенный символ есть знак пунктуации. Необходимости в портянке "str[i] != '.' || ..." нет.
Кроме того, у тебя функция с дополнительным побочным эффектом: кроме того, что она меняет строку, она еще печатает на экран результат. Для подобных функций следует такого избегать (если это не отладочный вывод): одна функция -- один результат или изменение каких-либо единичных данных (в данном случае строки).
Можно сделать так:
#include <ctype.h>
#include <stdio.h>
char *del_punct(char *s) {
char *c = s;
while (*c != '\0') {
if (ispunct(*c)) {
for (char *n = c; *n != '\0'; ++n) *n = *(n + 1);
} else {
++c;
}
}
return s;
}
int main() {
char s[128];
printf("string? ");
fgets(s, 128, stdin);
printf("%s", del_punct(s));
}
Кроме того, у тебя функция с дополнительным побочным эффектом: кроме того, что она меняет строку, она еще печатает на экран результат. Для подобных функций следует такого избегать (если это не отладочный вывод): одна функция -- один результат или изменение каких-либо единичных данных (в данном случае строки).
Можно сделать так:
#include <ctype.h>
#include <stdio.h>
char *del_punct(char *s) {
char *c = s;
while (*c != '\0') {
if (ispunct(*c)) {
for (char *n = c; *n != '\0'; ++n) *n = *(n + 1);
} else {
++c;
}
}
return s;
}
int main() {
char s[128];
printf("string? ");
fgets(s, 128, stdin);
printf("%s", del_punct(s));
}
Ну для начала стоит заметить что ваш код полностью не рабочий. Почему?
- Вы объявляете указатель char* strr2, при этом никак не инициализируете его (указатель на неопределённую область память), но присваиваете значения через него, что может привести к ошибке сегментации.
- Более того вам требовалось удалить знаки пунктуации. Необходимости перезаписывать один массив в другой - нету. Достаточно будет модифицировать массив *strr
- Вы сравниваете текущий символ со всеми знаками вручную, что делать необязательно и неэффективно. Таблица ASCII сконструирована так что каждый тип символов занимает некий диапазон, как к примеру 1 до 9, или A до Z, в том числе и знаки пунктуации.
- Циклы у вас сломаны, поэтому тут я ничего не могу сказать.
Вот правильный вариант:
#define ispunct(c) ((c > 0x20 && c < 0x30) || (c > 0x39 && c < 0x41) || (c > 0x5A && c < 0x61) || (c > 0x7A && c < 0x7F))
void delpunct(char* str)
{
char* s;
while (*str) if (ispunct(*str))
{
s = str++;
*s = *str;
while(*str)
{
if(!ispunct(*str)) *++s = *++str;
else *s = *++str;
}
return;
} else str++;
}
В отличии от алгоритма пользователя ra (который в худшем случае справляется за N^2 операций), этот работает за линейное время (N операций).
Таблица ASCII:

- Вы объявляете указатель char* strr2, при этом никак не инициализируете его (указатель на неопределённую область память), но присваиваете значения через него, что может привести к ошибке сегментации.
- Более того вам требовалось удалить знаки пунктуации. Необходимости перезаписывать один массив в другой - нету. Достаточно будет модифицировать массив *strr
- Вы сравниваете текущий символ со всеми знаками вручную, что делать необязательно и неэффективно. Таблица ASCII сконструирована так что каждый тип символов занимает некий диапазон, как к примеру 1 до 9, или A до Z, в том числе и знаки пунктуации.
- Циклы у вас сломаны, поэтому тут я ничего не могу сказать.
Вот правильный вариант:
#define ispunct(c) ((c > 0x20 && c < 0x30) || (c > 0x39 && c < 0x41) || (c > 0x5A && c < 0x61) || (c > 0x7A && c < 0x7F))
void delpunct(char* str)
{
char* s;
while (*str) if (ispunct(*str))
{
s = str++;
*s = *str;
while(*str)
{
if(!ispunct(*str)) *++s = *++str;
else *s = *++str;
}
return;
} else str++;
}
В отличии от алгоритма пользователя ra (который в худшем случае справляется за N^2 операций), этот работает за линейное время (N операций).
Таблица ASCII:

Похожие вопросы
- Как в языке си удалить строку из структуры?
- Язык си, не понял несколько моментов по массивам и строкам
- Почему язык СИ такой сложный?
- Совет по программе на языке си (строки)
- Программирование на языке СИ с использованием подпрограммы-функции
- удалить все элементы, кроме имеющих заданное произведение цифр. язык си++.нужна срочная помощь
- Программирование на языке Си. Нужна небольшая помощь.
- какую программу лучше использовать для программирования на языке Си?
- Вопрос тем, кто хорошо знаком с рекурсией. Язык Си (но это второстепенно)...
- Вопросы по языку СИ