Добавлено: 16 июн 2003, 14:30
А я этого и не отрецаю. Человек спросил - я, как мог, ответил.
Linux-портал Республики Беларусь
https://forum.linux.by/
Код: Выделить всё
#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;
}
За один проход (сложность 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);
}
А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.satanic_mechanic писал(а):to mend0za и иже с ним:
обычно вы (любители развитых средств обработки текста) говорите, что ваши примеры на perl, в bash и т. п. проще и во всю ругаете С (не все). Это всем давно известно. Но просили то код на C. Да и проще - не значит лучше (пример от kirya85 меньше). Все ведь зависит от ситуации. Проще пользователю. Но когда надо решать реальные задачи в больших приложениях. Когда критична скорость. Вы подумайте во что разворачиваются регулярные выражения в такой простой задаче (на уровне машинного кода).
Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.satanic_mechanic писал(а): Извините, наболело.
ЗЫ: насчет обработки текста в С согласен (но никто не мешает реализовать регекспы в нем).
Я тестил в gcc - работает.satanic_mechanic писал(а):]
ЗЫ: очень интересно - в каком компиляторе работает char b[strlen(a)];
по моему в квадратных скобках должна быть константа, вычисляемая во время компиляции, а не во время выполнения.
Код: Выделить всё
#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;
}
Я вроде говорил: все зависит от ситуации. Сравни по скорости прогу на С, специально написанную под данную задачу, и ту же прогу на перле с регулярными выражениями (при условии, что прога не криво написана). И дело не только в том, что Перл - интерпретатор. Регулярные выражения универсальны и очень удобны. А за это мы платим скоростью. Но дело даже не в этом. Я никоим образом не умаляю роль регулярных выражений. Просто когда задается вопрос о проге на С, а кому-то надо показать как он крут:А зачем думать? Сравнивать надо. Возьми большое-большое регулярное выражение, напиши аналог на C, и сравни c grep или awk на большом массиве текстов. Результаты тебя сильно-сильно удивят.
Мне кажется это называется оффтопик (а еще позерство, красование и т. п.) !!!!!.ruby -p -e '$_.gsub!(/ +/," ")'
perl -p -e 's/ +/ /'
awk '{gsub(/ +/," "); print}'
Опять извечное стремление кого-то обламать. Я не идиот и прекрасно понимаю, на чем реализован Perl, Python, PHP и т. п. языки. Я говорил о написании библиотеки на С и там же ее использования в свое удовольствие (говорил просто к слову). Реализация такая, какая тебе нравится (под себя), что бы о ней хотя бы сам программист (который ее напишет) хорошо отзывался. Я не выражал мнения, что регекспы реализованы на х.. знает чем. Не правда ли. А вы в желании меня обламать, занимаетесь искажением моих мыслей.Бред какой-то. А как ты думаешь, на чем реализованы regex engines в высокоуровневых языках? На них самих что-ли? Нет конечно. На C, как и сами языки. Тогда в чем разница использования регулярных выражений из высокоуровневых языков и С? Только в том, что реализация регулярных выражений в библиотеке pcre заставляет многих работавших с ней не очень хорошо о ней отзываться.