Вопрос по си

Модератор: Модераторы разделов

agreed
Сообщения: 143
ОС: Fedora 10, Mac OS X 10.5

Вопрос по си

Сообщение agreed »

Помогите! Измочалился уже весь! Требуется: функция, которая удаляет из нуль-строки все не ascii символы. Строку передавать по адресу.
Мой вариант(правда не силен я в си):

Код: Выделить всё

void delete_cyr(char * st[])
{
   int i,c;
   do {
      if (isascii(*(st[i])) *(st[c++]) = *(st[i]);
      ++i;
   } while( *(st[i]) != '\0');
}

Не могу понять, где я напартачил! :(
Спасибо сказали:
Аватара пользователя
JaGoTerr
Сообщения: 380

Re: Вопрос по си

Сообщение JaGoTerr »

Код: Выделить всё

void delete_cyr (char* source, char* result) {
    int counter = 0;
    while (*source != 0) {
        if (isascii (*source)) {
            result[counter++] = *source;
        }
        source++;
    }
    result[counter] = '\0';
}
Спасибо сказали:
agreed
Сообщения: 143
ОС: Fedora 10, Mac OS X 10.5

Re: Вопрос по си

Сообщение agreed »

Гм... Я что-то торможу... А почему нельзя вызывать delete_cyr(a,a), или еще лучше deletecyr(&a)? Промежуточные переменные (я про destination) - не очень удобно... :(
Спасибо сказали:
Аватара пользователя
JaGoTerr
Сообщения: 380

Re: Вопрос по си

Сообщение JaGoTerr »

Ну я вроде и не претендовал на то, что моя функция самая-самая и оптимальнее ничего в этом мире не существует. Я вообще не особо думал, когда писал. На автомате настрочил. Работает и ладно :)
Спасибо сказали:
agreed
Сообщения: 143
ОС: Fedora 10, Mac OS X 10.5

Re: Вопрос по си

Сообщение agreed »

Хе-хе.. :) Тогда внесу коррективы в условие: эта функция должна стать частью сервера, и вызываться порядка 10 раз в секунду. Наглухо забивать всю кодовую таблицу нельзя, исключительно в определенных ситуациях.
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: Вопрос по си

Сообщение oav »

Код: Выделить всё

void delete_cyr (char* source)
{
    char* res = source;
    char* it  = source;

    for(; *it != 0; ++it )
    {
  if (isascii (*it))
      continue;

  *res = *it;
  ++res;
    }
    source[res-source] = '\0';
}


зы. С - ужжжжасный язык
Спасибо сказали:
agreed
Сообщения: 143
ОС: Fedora 10, Mac OS X 10.5

Re: Вопрос по си

Сообщение agreed »

(oav @ Пятница, 25 Марта 2005, 14:25) писал(а):зы. С - ужжжжасный язык

Я тоже forth люблю... :) :) :)
По поводу исходника: "segmentation fault". :unsure:
Спасибо сказали:
Аватара пользователя
JaGoTerr
Сообщения: 380

Re: Вопрос по си

Сообщение JaGoTerr »

(agreed @ Пятница, 25 Марта 2005, 14:14) писал(а):Хе-хе..  :) Тогда внесу коррективы в условие: эта функция должна стать частью сервера, и вызываться порядка 10 раз в секунду.

Гы :) И чего? Да вызывай наздоровье.
1) от того, что ты уменьшишь кол-во параметров функции, во сто крат быстрее работать она не станет. Она вообще не станет работать быстрее, ни во сколько раз. Потому что скажу тебе честно: тут вызов функции по стоимости сравним с исполнением самой этой функции, посему единственной оптимизацией для неё можеть быть 'inline' . Да и то, я думаю компилятор это и сам сообразит. Всё остальное - мартышкин труд.
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: Вопрос по си

Сообщение oav »

(agreed @ Пятница, 25 Марта 2005, 15:53) писал(а):
(oav @ Пятница, 25 Марта 2005, 14:25) писал(а):зы. С - ужжжжасный язык

Я тоже forth люблю... :) :) :)
По поводу исходника: "segmentation fault". :unsure:


ну звиняй - писал на колнке - мож чего упустил. если честно на вскидку сегфолта не вижу. Какая строка на входе?

oav добавил в 25.03.2005 15:36

(oav @ Пятница, 25 Марта 2005, 16:32) писал(а):
(agreed @ Пятница, 25 Марта 2005, 15:53) писал(а):
(oav @ Пятница, 25 Марта 2005, 14:25) писал(а):зы. С - ужжжжасный язык

Я тоже forth люблю... :) :) :)
По поводу исходника: "segmentation fault". :unsure:


ну звиняй - писал на колнке - мож чего упустил. если честно на вскидку сегфолта не вижу. Какая строка на входе?



надеюсь вызывал не так?

Код: Выделить всё

char* test_string = "AASAAS";
delete_cyr( test_string);

Если да, то надо вот так :

Код: Выделить всё

char test_string[] = "AASAAS";
delete_cyr( test_string);
Спасибо сказали:
Аватара пользователя
JaGoTerr
Сообщения: 380

Re: Вопрос по си

Сообщение JaGoTerr »

Ну раз так, то можно и ещё короче. Без счётчика и лишнего указателя.

Код: Выделить всё

void delete_cyr2 (char* s) {
    char* r = s;
    for (; *s != 0; s++) {
        if (isascii (*s)) {
            *r = *s;
            r++;
        }
    }
    *r = '\0';
}

В сторону и шёпотом: тьфу, чтоб не делать, лишь бы не работать. Всё, надо взять себя в руки.
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: Вопрос по си

Сообщение oav »

Я и форт не люблю (вернее, не знаю) и С не люблю. С++ люблю и то не всегда. Но для такой задачи вполне даже люблю:

Код: Выделить всё

std::string str = "11aabb11kk33j";
str.erase( std::remove_if( str.begin() , str.end() , std::ptr_fun(isdigit) ) , str.end());


зы. вместе isdigit подставь любой придикат с любыми параметрами и даже состоянием
Спасибо сказали:
agreed
Сообщения: 143
ОС: Fedora 10, Mac OS X 10.5

Re: Вопрос по си

Сообщение agreed »

надеюсь вызывал не так?

Код: Выделить всё

char* test_string = "AASAAS";
delete_cyr( test_string);

Если да, то надо вот так :

Код: Выделить всё

char test_string[] = "AASAAS";
delete_cyr( test_string);



Типа, опа! :) Извини - работает! А можно объяснить - в чем разница? В книге не нашел...

agreed добавил в 25.03.2005 19:05

(oav @ Пятница, 25 Марта 2005, 17:24) писал(а):Я и форт не люблю (вернее, не знаю) и С не люблю. С++ люблю  и то не всегда. Но для такой задачи вполне даже люблю:

Спасибо, конечно, но функция нужна именно на си. На си++ я получше разговариваю... А с фортом стоит хотя бы познакомиться. Потрясающий язык. Пожалуй, forth + python + c - это все, что для жизни нужно. :thumbsup: Ну и ессно без с++ щас никуда, хотя не люблю я его...
Еще раз спасибо всем за исходники, считаю тему закрытой!
Спасибо сказали:
Аватара пользователя
oav
Бывший модератор
Сообщения: 296

Re: Вопрос по си

Сообщение oav »

надеюсь вызывал не так?

Код: Выделить всё

char* test_string = "AASAAS";
delete_cyr( test_string);

Если да, то надо вот так :

Код: Выделить всё

char test_string[] = "AASAAS";
delete_cyr( test_string);



Типа, опа! :) Извини - работает! А можно объяснить - в чем разница? В книге не нашел..

Разница в способе выделения памяти под эту строку. В первом случае gcc выделает в сегменте константных данных (а функция пытается их менять - и соотв. падает), а во втором выделяется обычный массив в стеке.
Спасибо, конечно, но функция нужна именно на си. На си++ я получше разговариваю... А с фортом стоит хотя бы познакомиться. Потрясающий язык. Пожалуй, forth + python + c - это все, что  для жизни нужно. :thumbsup: Ну и ессно без с++ щас никуда, хотя не люблю я его...
Еще раз спасибо всем за исходники, считаю тему закрытой!

Из стековых языков я лучше MSIL изучу (что по-тихоньку и делаю). Незачто
Спасибо сказали: