LINUX.ORG.RU

char* del_space(char *s)
{int i,j;
char *s_new=(char*)malloc(sizeof(char)*strlen(s));
int flag=0;
for(i=0;i<strlen(s);i++)
{if((s[i]==' ')&&(flag==0)){flag=1;s_new[j]=s[i];j++;}
if(s[i]!=' ') {flag=0;s_new[j]=s[i];j++;}
}
return s_new;
}

Помоему должно работать.

ex2
()

int
strip_spaces(const char *src, char *dst, int size)
{
    int in_space = 0;
    int count = size - 1;

    if(!src || !dst || (size < 0))
        return -1;

    while(*src && (count >= 0))
    {
        if(!in_space)
        {
            if(*src == ' ')
            {
                in_space = 1;
            }
            *dst++ = *src++, --count;
        }
        else
        {
            if(*src == ' ')
            {
                src++;
            }
            else
            {
                in_space = 0;
            }
        }
    }
    *dst = '\0';
    return size - count - 1;
}

anonymous
()
Ответ на: комментарий от anonymous

Извинясь - обделался. Следует читать:

while(*src && (count > 0))



anonymous
()

не работает:(

сам компилер не ругается но в итоге при запуске софтины пишет Segmentation fault

anonymous
()

спасибо

anonymous
()

Мда. Как и следовало ожидать с указателями народ работать не умеет.

char *strip_spaces( char *pszStr )
{
   char *pszOld = pszStr;
   char *pszCur = pszStr;

   if( pszStr )
   {
      for( ; *pszCur; pszCur++ )
      {
         if( pszCur[1] != ' ' || pszCur[0] != ' ' )
            *pszStr++ = *pszCur;
      }

      *pszStr = *pszCur; // скопировать \0
   }

   return pszOld;
}

Ogr
()
Ответ на: комментарий от Ogr

И это у вас работает? Какой компилятор, если не секрет?

-----
main()
{
    static char *str = "Hello";

    puts("Run test");
    puts(strip_spaces(str));

    return 0;
}
----

> Как и следовало ожидать с указателями народ работать не умеет.

Ну вы то умеете. Вон даже и psz приписываете.


anonymous
()

А со static ни кто не обещал, что будет работать. К тому же функция реализован из тех же принципов что и станадртная strcat, так что притензии по параметрам к Кернигану на пару с Риччи. Ну а то что мой вариант куда проще чем пионерские поделки я думаю, ты по своей не далекости, не заметил.

PS psz я пишу для себя, а не для кого-то.
PPS Таких притензий, как длинный и не оптимальный код я так понимаю нет. Так что жду слов "Спасибо"...

Ogr
()
Ответ на: комментарий от Ogr

> А со static ни кто не обещал, что будет работать.

Работать должно всегда. Кстати static можете убрать.

> К тому же функция реализован из тех же принципов что и станадртная strcat, так что притензии по параметрам к Кернигану на пару с Риччи.

ПрИтензии? Ни в коем случае. Но делать такие гнилые вещи, как модификация на месте, и советовать их делать другим - нехорошо.

> Ну а то что мой вариант куда проще чем пионерские поделки я думаю, ты по своей не далекости, не заметил.

Проще == меньше строчек? Ладно. Но все равно не работает.

> PS psz я пишу для себя, а не для кого-то.

Вот они - org'ские привычки: венгерская нотация и уверенность, что код не будет прочитан.

> PPS Таких притензий, как длинный и не оптимальный код я так понимаю нет. Так что жду слов "Спасибо"...

Спасибо за потраченное время. Код - опасный. Пишется "претензия".

anonymous
()

Хотя нет, есть у меня проблема в "корректности" кода, но пионеры всё равно её не заметят. Так что можно считать, что преблемы нет.

Ogr
()

> Работать должно всегда. Кстати static можете убрать.

Будет работать как хавещал Керниган и Ричи. У тебя к ним проблемы?

> ПрИтензии? Ни в коем случае. Но делать такие гнилые вещи, как модификация на месте, и советовать их делать другим - нехорошо.

У-ха ха... Глянь на strcat и тихо заткнись.

> Проще == меньше строчек? Ладно. Но все равно не работает

А ты попробуй прежде чем говорить.

> Вот они - org'ские привычки: венгерская нотация и уверенность, что код не будет прочитан

И? Тебе она мешает? Мне нет.

> Спасибо за потраченное время. Код - опасный

И чем же он опасен? Тем что народ видит, как криво пионеры реализовали простейшую функцию используя какие-то не понятные флаги состояний?

Ogr
()
Ответ на: комментарий от Ogr

> Будет работать как хавещал Керниган и Ричи.

Вы проверяли?

> У тебя к ним проблемы?

К ним?

> У-ха ха... Глянь на strcat и тихо заткнись.

Опять оправдываетесь, кивая в сторону?

> А ты попробуй прежде чем говорить.

Я-то попробовал.

> И? Тебе она мешает? Мне нет.

Ну извините.

> И чем же он опасен?

Пример копилировали/запускали?

> Тем что народ видит, как криво пионеры реализовали простейшую функцию используя какие-то не понятные флаги состояний?

Вам не понятно? Ну-ну.

anonymous
()

В общем так - какие претензии? Код работает - проверенно. Ты сам-то проверял?
Использовать state-machine для этого случая - полное убожество.

Ogr
()

> В общем так - какие претензии?

Претензия одна - ужасающий побочный эффект. Пользователи этой функции получают возможность натворить всяких ужасов.

> Код работает - проверенно. Ты сам-то проверял?

Проверял на примере от 2003-06-16 23:11:56.137365 - получил segfault, как и следовало ожидать.

> Использовать state-machine для этого случая - полное убожество.

Так и случай такой.

anonymous
()

2anonymous (*) (2003-06-17 01:38:51.885287):

> Претензия одна - ужасающий побочный эффект

Какой побочный эффект? Модификация строки? Ты man strcat набирал или нет? Ты где-нибудь видел слово static в объявлении параметра функции? Может ты того... Почитаешь что-нибудь скажем того же Кернигана, прежде чем тут говорить?

> Проверял на примере от 2003-06-16 23:11:56.137365 - получил segfault, как и следовало ожидать

Ты язык С знаешь? Мне кажется что нет. Опять таки сделай man strcat прежед чем говорить.

> Так и случай такой.

Тут случай такой, что ни какая state-machine не нужна. Просто нужно видеть решение задачи.

PS Ты автор какой реализации? Первой или второй? А то у меня ко второй реализации очень большие претензии.

Ogr
()

Мда... В общем до тебя так и не дошло. Подсказываю: прочитай книжку на тему char *blah = "blah-blah" и char blah[] = "blah-blah"

Как тебе ещё объяснить твою глупость я не знаю.

PS Чтоб не было вопросов: код проверялся на
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

Ogr
()
Ответ на: комментарий от Ogr

> Какой побочный эффект? Модификация строки? Ты man strcat набирал или нет?

Ну так. Давно известно, что strcat - проблемная функция.

> Ты где-нибудь видел слово static в объявлении параметра функции?

Это вы к чему? Поясните пожалуйста.

> Может ты того... Почитаешь что-нибудь скажем того же Кернигана, прежде чем тут говорить?

Читал.

> Ты язык С знаешь? Мне кажется что нет. Опять таки сделай man strcat прежед чем говорить.

Что вы постоянно киваете на strcat? Плохая это функция. Хорошая выглядела бы так: int str_cat(const char *part1, const char *part2, char *dst, int size);

> Тут случай такой, что ни какая state-machine не нужна. Просто нужно видеть решение задачи.

Тут я с вами и не особо спорил. Но какие у вас возражения? Пример дюже простой?

> PS Ты автор какой реализации? Первой или второй? А то у меня ко второй реализации очень большие претензии.

Второй. Но у меня к ней у самого остались претензии - входные условия неправильно проверяет (не хотел исправлять - раз уж тут спор развязался). Очень интересно услышать ваши претензии.

anonymous
()

> Мда... В общем до тебя так и не дошло. Подсказываю: прочитай книжку на тему char *blah = "blah-blah" и char blah[] = "blah-blah"

Это до вас не дошло. Различие я прекрасно знаю. Но пример есть? Компилится? Сегфаултится?

> Как тебе ещё объяснить твою глупость я не знаю.

Да уж как-нибудь постарайтесь, автор безопасной функции, к которой нужно прилагать инструкцию по использованию.

anonymous
()

> Давно известно, что strcat - проблемная функция

У strcat всего одна проблема - не проверяет длину строки куда копировать, а в остальном проблем нет. Не зря была придумана strncat. Но моя функция такой проблемы не имеет по очевидным причинам.

>> Ты где-нибудь видел слово static в объявлении параметра функции?

> Это вы к чему? Поясните пожалуйста.

Имелось ввиду const (а не статик), если бы было написано strip_spaces( const char *pszStr ) То юзер видел бы, что строку модифицировать не будут, а раз const нет, то будут. У тебя с этим проблемы?

> Что вы постоянно киваете на strcat? Плохая это функция

Хорошая функция, делает ровно то что заказывали - соединяет две строки и без кучи лишних параметров и очень удобно пользоватся: strcat( strcat( str ), str2 )

> Второй. Но у меня к ней у самого остались претензии - входные условия неправильно проверяет (не хотел исправлять - раз уж тут спор развязался). Очень интересно услышать ваши претензии

Всегда пожалуйста:

1) size должен быть не int, а size_t

2) Может проще было всю эту конструкцию через for сделать, хоть смотрелась бы более проще.

> Это до вас не дошло. Различие я прекрасно знаю. Но пример есть? Компилится? Сегфаултится?

Какой сегфолтится char *? Так ему Керниган завещал сегфолтится. А вот char [] прекрасно работает.

> Да уж как-нибудь постарайтесь, автор безопасной функции, к которой нужно прилагать инструкцию по использованию.

Функция безопасна, потому как её прототип является наглядной документацией.

Ogr
()

Я другой ананимус.
Мне лично понравился код со состоянием (только я бы его переделал бы по своему), но испльзовал бы, как Ogr, одну строковую переменную.

примерно так (не тестировал):
char *strip_spaces(char *src)
{
int in_space = 0;
char *dst=src;
cahr *ret=src;

if(!src)return NULL;

while(*src)
if(!in_space)
in_space = (*src == ' '), *dst++ = *src++;
else
if(in_space = (*str == ' ')) src++;

*dst = '\0';
return ret;
}

Может, кому не понравится, не претендую на шедер. В варианте Ogr, мне не понравилось смесь обращения к содержимому указателей и индексов.

anonymous
()

не... погодь... я серьезно спрашиваю. адепты языка, че ж вы заткнулись?

anonymous
()

/*
 * try this,
 * to prevent memory leaks
 * you should get free the result string 
 * if you dont need it anymore 
 * sorry for english, I hate translit :-)
 */
char *trim(char *str)
{
    char *buf, *p;

    if (!str)
	return NULL;

    if (!(buf = (char *) calloc(strlen(str) + 1, 1)))
    	exit(1);
    
    p = buf;
    while (*str) {
    	*p++ = *str++;
	if (*(p - 1) == ' ') 
	    while (*str == ' ')
		str++;
    }
    
    buf = (char *) realloc(buf, strlen(buf) + 1);

    return buf;
}
 
agat

anonymous
()

2anonymous (*) (2003-06-17 09:02:23.438704):

> В варианте Ogr, мне не понравилось смесь обращения к содержимому указателей и индексов.

Я же говорю, не умеет народ с указателями работать. Вот их и пугает указатели с индексами... Ну напиши так: if( *(pszCur+1) != ' ' || *pszCur != ' ' ) для компилятора абсолютно ни какой разницы.

2anonymous (*) (2003-06-17 10:32:05.41423):

>  я так и не понял char* raz = "blah"; char dva[] = "blah"; и шо? где разница?

int main( void )
{
  char str1[] = "This is a first string";
  char *str2  = "This is a second string";

  puts( "Start test:" );

  puts( strip_spaces(str1) );
  puts( strip_spaces(str2) );

  return 0;
}

Запусти это на линуксе, используя мою функцию, и прочуствуй разницу. Может К&R прочитаешь за одно.

Ogr
()

если я не ошибаюсь, то
str[]="типа моя строчка";
означает, что память - таки выделена и эту строку можно
менять, работая указателем.*(str+1) = 'р';
*str="типа ещё моя строчка"; При попытке изменить
выдаст Segmentation Fault. Вот так.

solom
()

Разница между char * и char [] в том, что char *str = "str" указывает на статическую область памяти и соответсвенно изменение в этой области может привести к coredump, в то время как char str[] = "str" выделяет память под объект в области данных (в данном случае стека) и дает возможность менять содержимое строки.

Ogr
()

>> В варианте Ogr, мне не понравилось смесь обращения к содержимому указателей и индексов.

>Я же говорю, не умеет народ с указателями работать. Вот их и пугает указатели с индексами... Ну напиши так: if( *(pszCur+1) != ' ' || *pszCur != ' ' ) для компилятора абсолютно ни какой разницы.

Ну, дык, и написал бы так, а то отговорки начались. Если * - то указатель, если [] - то индекс.

И зачем, каждую позицию, ты проверяешь дважды на равенство с пробелом? С первого раза не понимаешь? :)

> *pszStr = *pszCur; // скопировать \0
И нулевой символ можно порсто присвоить, зачем его доставать из памяти.

Если серьёзно, это я так прикапываюсь. Но обвинять народ, что не умеет работать с указателями, не надо.

anonymous
()

Тут что, устроили конкурс "тысяча и один способ убрать повторяющиеся пробелы" :-) ?

Тогда и я свой вариант подкину:

char* remove_double_spaces(char *str)
{
  char *src = str, *dst = str;

  while(*src){/*Перебираем строку*/
    if (*src==' '){
      while (*(++src)==' ');/*Если пробел, значит не '\0'*/
      *(dst++) = src[-1];/*Копируем последний (или единственный) пробел*/
    }
    else
      *(dst++) = *(src++);
  }
  *dst = '\0';  //*src;

  return str;
}

DKorolkov
()

Народ! я первый анонимус, что запостил вопрос...

честно поражен!

я сам конечно написал по своему... но я не ждал что вы столько запостите и что этот вопрос вызовет такой интерес!

огромное спасибо все ваши способы сложу себе в копилку идей)))

anonymous
()
Ответ на: комментарий от anonymous

Мои ржавые 2 копейки


Вариант Ogr всем хорош, есть только одна непонятка, именно, зачем нужна проверка аргумента на 0.
Поясняю. У функции есть как минимум 4 способа налететь на segfault и иже с ним:
1. Аргумент равен 0
2. Аргумент указывает на read-only memory (обсуждалось)
3. Аргумент указывает вообще черт знает куда
4. Аргумент указывает в хорошее место, но лежит там не строка (так что цикл завершится не по условию, а опять-таки аварийно).

Зачем из четырех равноправных ошибок проверять одну?

vnp
()

проблема в том что если в какой то момент времени pszCurr(или как
его там) указывает на последний байт байт на границе, то есть картинка
выглядит так:

min -----> max /* куда растет паметь */

---read-write-memory---+---out-of-bound-memory---
               ... |3|7| 
-----------------------+-------------------------
                      ^
                      |
                   pszCurr

то есть значение *pszCurr равно pszCurr[0] равно 7 - цикл продолжается,
но в момент доступа к pszCurr[1] будет обращение к левой памяти
которая не в поле зрения процесса то есть возникнет ошибка.

lg ★★
()

хотя с другой стороны где то в видимой области должен быть '\0' :)

эй lg хорошь бухать

lg ★★
()

Да кстати, чтоб программа была совсем правильная выражение: pszCur[0] != ' ' должно быть записано как !isspace( pszCur[0] ), в таком случае программа правильно будет работать даже в многоязычной среде. Хотя для char * это смысла мало имеет, а вот для wchar_t * очень даже...

Ogr
()

Хотя лично мне понравился подход agat... Он отрботает побыстрее моего.

Ogr
()

> Хотя лично мне понравился подход agat... Он отрботает побыстрее моего.

С вызовами strlen, calloc и realloc? Не смешите.

anonymous
()
Ответ на: комментарий от Ogr

> Хорошая функция, делает ровно то что заказывали - соединяет две строки и без кучи лишних параметров и очень удобно пользоватся: strcat( strcat( str ), str2 )

Вы бы привели типичный кусок кода, использующего strcat. Сам вызов прост, но требует нехилой обвязки. _Один_ лишний параметр - небольшая цена за удобство.

> size должен быть не int, а size_t

Личное дело каждого. Если я изменю имя size на count, вы разрешите переменной быть типа int? (Ну не нравится мне unsigned - с нулем очень неудобно сравнивать).

> Может проще было всю эту конструкцию через for сделать, хоть смотрелась бы более проще.

А что там выносить наверх, кроме src++? А проще/непроще - главное точнее выражает идею.

anonymous
()

2anonymous (*) (2003-06-20 02:32:57.180729):

> С вызовами strlen, calloc и realloc? Не смешите.

Я не про подход, а не про alloc, который заключается в отсутсвии флагов и лишних проверок.

> Вы бы привели типичный кусок кода, использующего strcat. Сам вызов прост, но требует нехилой обвязки

Для этого и существует strncat чтоб без обвязки.

> А что там выносить наверх, кроме src++?

За-то наглядно показывает по какому параметру цикл.

Ogr
()

to anonymous (*) (2003-06-20 02:32:57.180729):

> С вызовами strlen, calloc и realloc? Не смешите. 

char *trim(char *str)
{
    char *buf, *p;

    if (!str)
	return NULL;

    buf = str;  
    p = buf;

    while (*str) {
    	*p++ = *str++;
	if (*(p - 1) == ' ') 
	    while (*str == ' ')
                str++;
    }

    *p = '\0';
    
    return buf;
}

конечно можно и так, но тогда будет проблема 
с char* / char[]. Ну а realloc в принципе тоже не так уж
глупо - если функция вызывается редко и str имеет большое
кол-во пробелов. Не нравится - закомментируй.

agat
()

> Для этого и существует strncat чтоб без обвязки.

Нет, я про случай, когда в dest недостаточно места под добавляемую строку, а добавить все-таки НУЖНО.

anonymous
()
Ответ на: комментарий от agat

> конечно можно и так, но тогда будет проблема с char* / char[].

Проблема возникает только если делать модификацию на месте, вот мне и интересно - ЗАЧЕМ?

> Ну а realloc в принципе тоже не так уж глупо - если функция вызывается редко и str имеет большое кол-во пробелов. Не нравится - закомментируй.

Если функция вызывается редко - к чему вообще заботится об эффективности?

anonymous
()

2anonymous (*) (2003-06-20 03:47:41.14478):

> Нет, я про случай, когда в dest недостаточно места под добавляемую строку, а добавить все-таки НУЖНО.

Тебе написать как будет выглядеть функция strncatNoMatterWhat()?

Ogr
()

> Тебе написать как будет выглядеть функция strncatNoMatterWhat()?

Лучше выложите где-нибудь её фотографию.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.