Функция на C которая удаляет повторяющиеся пробелы из char*
Кстати, в qbasic была функция, которая меняла одну подстрку на другую... Неужели в С такого нет?
Кстати, вот вам без re, если так уж хочется изврата
#!/usr/bin/python2.2
from UserString import UserString
class mystring(UserString):
def midtrim(self):
while not ( self.data == self.data.replace(' ',' ') ):
self.data = self.data.replace(' ',' ')
return self.data
a = mystring('123 456')
print a.midtrim()
Кстати, вот вам без re, если так уж хочется изврата
#!/usr/bin/python2.2
from UserString import UserString
class mystring(UserString):
def midtrim(self):
while not ( self.data == self.data.replace(' ',' ') ):
self.data = self.data.replace(' ',' ')
return self.data
a = mystring('123 456')
print a.midtrim()
Опыт растет прямо пропорционально выведенному из строя оборудованию
Немного оптимизированная версия

Код: Выделить всё
#include <stdio.h>
#include <string.h>
char* strip_spaces(const char* in, char* out)
{
char *p;
p = out;
strcpy(out,in);
while(1)
{
p = strstr(p," ");
if (p==NULL) break;
strcpy(p+1,p+2);
}
return out;
}
int main()
{
char *a = "ab raka da b r a";
char b[strlen(a)];
strip_spaces(a,b);
printf("%s\n",a);
printf("%s\n",b);
return 0;
}
- Говорят, пингвин - это ласточка разжиревшая от лени?
- Нет. Это ласточка беременная мыслью.
- Нет. Это ласточка беременная мыслью.
Спасибо, правильное замечание. Вот пофиксеная версия:Lynxer писал(а):strcpy нельзя использовать для копирования перекрывающихся строк. Может свезти, а может и нет. Лучше использовать memmove.
Код: Выделить всё
#include <stdio.h>
#include <string.h>
char* strip_spaces(const char* in, char* out)
{
char *p;
int len;
p = out;
strcpy(out,in);
while(1)
{
p = strstr(p," ");
if (p==NULL) break;
len = strlen(p+2);
memmove(p+1,p+2,len);
*(p+1+len)='\0';
}
return out;
}
int main()
{
char *a = "ab raka da b r a";
char b[strlen(a)];
strip_spaces(a,b);
printf("%s\n",a);
printf("%s\n",b);
return 0;
}
- Говорят, пингвин - это ласточка разжиревшая от лени?
- Нет. Это ласточка беременная мыслью.
- Нет. Это ласточка беременная мыслью.
- satanic_mechanic
- Интересующийся
- Сообщения: 56
- Зарегистрирован: 18 июл 2003, 01:36
- Контактная информация:
Извините за запоздалый ответ. Просто я считаю все примеры на С кривоватыми.
Там и strlen, и strstr, и memmove. Да еще удаляется по пробелу за проход этих функций. Подумайте, как это будет в машинных кодах. Да и о количестве проходов. Уж очень "оптмизированные" версии.
ЗЫ: очень интересно - в каком компиляторе работает char b[strlen(a)];
по моему в квадратных скобках должна быть константа, вычисляемая во время компиляции, а не во время выполнения.
Там и strlen, и strstr, и memmove. Да еще удаляется по пробелу за проход этих функций. Подумайте, как это будет в машинных кодах. Да и о количестве проходов. Уж очень "оптмизированные" версии.
За один проход (сложность O(n) ):Программирование это не знание какого-либо языка. Это мышление.
Код: Выделить всё
#include <stdio.h>
short strip (const char *from, char *to) // возвращает длину новой строки (включая '\0')
{
short i = 0, p = 0;
short state = 0; // простенький конечный автомат
// 0 - после любого символа
// 1 - после пробела
while (from[i]) {
if (from[i] == ' ') {
if (state == 0) {
to[p++] = ' ';
state = 1;
}
} else {
to[p++] = from[i];
if (state == 1)
state = 0;
}
++i;
}
to[p++] = '\0';
return (p);
}
void main ()
{
char a[28] = "ab ra ka da bra";
char b[28];
strip (a, b);
printf ("a : %s\nb : %s\n", a, b);
}
по моему в квадратных скобках должна быть константа, вычисляемая во время компиляции, а не во время выполнения.
Последний раз редактировалось satanic_mechanic 18 июл 2003, 11:30, всего редактировалось 1 раз.
- satanic_mechanic
- Интересующийся
- Сообщения: 56
- Зарегистрирован: 18 июл 2003, 01:36
- Контактная информация:
Короче
to mend0za и иже с ним:
обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).
Извините, наболело.
ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).
обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).
Извините, наболело.
ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).
- leikind
- Неотъемлемая часть форума
- Сообщения: 811
- Зарегистрирован: 20 июн 2002, 03:02
- Откуда: Брюссель
- Контактная информация:
Re: Короче
А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.satanic_mechanic писал(а):to mend0za и иже с ним:
обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).
Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.satanic_mechanic писал(а): Извините, наболело.
ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).
А как вам такой вариант:
PS Может кто протестит производительность последних двух вариантов или раскажет как это грамотно сделать?
Код: Выделить всё
#include <stdio.h>
#include <string.h>
char* strip_spaces(const char* in, char* out)
{
const char *p1, *p2;
int l=0;
p1 = in;
while(1)
{
p2 = strstr(p1," ");
if (p2 == NULL){
strcpy(out + l,p1);
break;
}
if (p2 != p1){
memcpy(out + l, p1, p2 - p1);
l += p2 - p1;
}
p1 = p2 + 1;
}
return out;
}
int main()
{
char *a = "ab raka da b r a";
char b[strlen(a)];
strip_spaces(a,b);
printf("%s\n",a);
printf("%s\n",b);
return 0;
}
- Говорят, пингвин - это ласточка разжиревшая от лени?
- Нет. Это ласточка беременная мыслью.
- Нет. Это ласточка беременная мыслью.
- satanic_mechanic
- Интересующийся
- Сообщения: 56
- Зарегистрирован: 18 июл 2003, 01:36
- Контактная информация:
[to leikind]
PS. Извините за грубость, но на этом форуме я вообще часто вижу, как на новичков начинают гнать так, что у них во всю отпадает охота что-либо спрашивать. И это линукс-сообщество. Сообщество людей, которые считают, что они круче всех и при каждой возможности пытаются показать это ;(((
// это касается не всех, да и большинства не касается ... но это правда
Я вроде говорил: все зависит от ситуации. Сравни по скорости прогу на С, специально написанную под данную задачу, и ту же прогу на перле с регулярными выражениями (при условии, что прога не криво написана). И дело не только в том, что Перл - интерпретатор. Регулярные выражения универсальны и очень удобны. А за это мы платим скоростью. Но дело даже не в этом. Я никоим образом не умаляю роль регулярных выражений. Просто когда задается вопрос о проге на С, а кому-то надо показать как он крут:А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.
Мне кажется это называется оффтопик (а еще позерство, красование и т. п.) !!!!!.ruby -p -e '$_.gsub!(/ +/," ")'
perl -p -e 's/ +/ /'
awk '{gsub(/ +/," "); print}'
Опять извечное стремление кого-то обламать. Я не идиот и прекрасно понимаю, на чем реализован Perl, Python, PHP и т. п. языки. Я говорил о написании библиотеки на С и там же ее использования в свое удовольствие (говорил просто к слову). Реализация такая, какая тебе нравится (под себя), что бы о ней хотя бы сам программист (который ее напишет) хорошо отзывался. Я не выражал мнения, что регекспы реализованы на х.. знает чем. Не правда ли. А вы в желании меня обламать, занимаетесь искажением моих мыслей.Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.
PS. Извините за грубость, но на этом форуме я вообще часто вижу, как на новичков начинают гнать так, что у них во всю отпадает охота что-либо спрашивать. И это линукс-сообщество. Сообщество людей, которые считают, что они круче всех и при каждой возможности пытаются показать это ;(((
// это касается не всех, да и большинства не касается ... но это правда