удалить в строке Char заданный символ

Тема в разделе "Общие вопросы по С и С++", создана пользователем tanil72, 25 апр 2008.

Статус темы:
Закрыта.
  1. tanil72

    tanil72 Гость

    Здравствуйте.
    Стоит задача ввести строку char с клавиатуры, вывести ее на экран и удалить в ней заданный символ.
    Код следующий. Подпрограмма удаления вынесена в отдельную функцию. Но удаление символа проходит неправильно.
    Подскажите, в чем ошибка.
    Спасибо.

    [codebox]#include <iostream>
    #include <stdio.h>
    using namespace std;

    char* del_char(char* s, char c){
    // int s_len=strlen(s); char *p=new char[s_len-1];
    char *p=s; int i=0;
    while(s!='\0'){
    if(s!=c) p=s;
    else p=s[i+1];
    i++;
    }
    *p='\0';
    return p;
    }

    int main(){
    int i, n=100;
    char *s=new char[n];
    char *tmp=new char[n-1];
    char d='p';
    cout<<"Vvedite stroku"<<endl;
    cin.getline(s,n);
    for(i=0;i<n;i++)
    cout<<s;cout<<endl;

    tmp=del_char(s,d);
    for(i=0;i<n;i++)
    cout<<tmp;cout<<endl;
    return(0);
    }[/codebox]
     
  2. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    А отлаживаться вас не учат? Давай я научу. Берешь листик бумаги и ручку, записываешь в строчку имена локальных переменных, палец левой руки ставишь на первую строчку функции, правой записываешь под именами начальные значения. Теперь делаешь шаг левой рукой вниз на одну строчку, правой записываешь изменившиеся переменные. Продолжать пока реальные значения переменных не станут отличаться от ожидаемых. В результате даже без компьютера находишь ошибки у себя в программе. Заодно начинаешь понимать что же собственно у тебя написано.
     
  3. tanil72

    tanil72 Гость

    Может логика неправильная- поправьте (я новичок).
    Длина строка с удаленным символом будет на 1 меньше.
    Переписываю в новую строку по-элементно символы введенной строки,
    а заданный символ пропускаю (пока не конец введенной строки).
    Может есть станд. функция удаляющая символ?

     
  4. Dimmuborgir

    Dimmuborgir Гость

    думаю, дело в алгоритме удаления.)
    Код (Text):
    if(s[i]!=c)  
    p[i]=s[i];
    else  
    p[i]=s[i+1];
    неверное услоиве. по этому условию сдвигается на единицу только символ стоящий после нужного. Необходимо как я понимаю сдвигать все символы находящиеся после заданного. Как это сделать, я думаю сами додумаетесь.
     
  5. shisik

    shisik Well-Known Member

    Регистрация:
    26 авг 2007
    Сообщения:
    154
    Симпатии:
    0
    Так всё работает :)
    Код (Text):
    #include <iostream>

    using namespace std;

    char * del_char(const char * src, char * res, char c)
    {
    char *tmp = res;
    do
    if (*src != c)
    *res++ = *src;
    while (*src++);
    return tmp;
    }

    int main(int argc, char *argv[])
    {
    char str[256], buf[256];

    cin >> str;

    cout << del_char(str, buf, 'a') << endl;

    return 0;
    }
    Даже символ '\0' в конец строки добавляет автоматически из строки исходной :)
     
  6. tanil72

    tanil72 Гость

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

    [codebox]#include <iostream>
    using namespace std;

    char * del_char(char * s, char c){
    int count=0;
    char *p, char*r, char*res;
    for(r=s;r=strchr(r,c);r+=sizeof(с))++count;
    p=result=(char*)malloc(strlen(s)-sizeof(с)*count+1);
    int i=0,j=0;
    while(s!='\0'){
    if(s!=c) p[j]=s;
    else p[j]=s[++i];
    i++;j++;
    }
    p[j]='\0';
    return p;
    }

    int main()
    {int n=100;
    char *s=new char[n];
    char *tmp=new char[n];
    char d='p';
    cout<<"vvedite stroku"<<endl;
    cin.getline(s,n);
    cout<<s<<endl;

    tmp=del_char(s,d);

    cout<<tmp<<endl;
    return 0;
    }
    [/codebox]
     
  7. shisik

    shisik Well-Known Member

    Регистрация:
    26 авг 2007
    Сообщения:
    154
    Симпатии:
    0
    Это потому, что алгоритм неправильный. Ошибка заключается в том, что в операторе
    Код (Text):
    if (s[i] != c)
    p[j]=s[i];
    else
    p[j]=s[++i];
    i++;j++;
    не нужно писать else. Я имею ввиду, что ты принудительно смещаешь исходную строку на один символ и без всяких проверок записываешь этот символ в результат. Поэтому второе подряд вхождения оно и не удаляет. Собственно, если этот участок переписать
    Код (Text):
    if (s[i] != c)
    p[j++]=s[i];
    i++;
    то эта проблема должна решиться (извини, проверять сейчас как-то неохота).

    И ещё вопрос. Зачем под p выделять память динамически? Да ещё и через malloc (в C++, имхо, проще использовать new). Получается, что теперь после вызова del_char() следует вызывать free() или delete (в случае использования new). И ещё меня смущает вызов
    Код (Text):
    char *tmp=new char[n];
    а затем
    Код (Text):
    tmp=del_char(s,d);
     
  8. tanil72

    tanil72 Гость

    Спасибо. Это была ошибка в логике. else не нужно.
    Я думала, что важно знать точно длину результирующей строки и поэтому вычисляла
    Код (Text):
    char* r; for(r=s;r=strchr(r,c);r+=sizeof(с))++count;
    unsigned int tmp_len=strlen(s)-sizeof(d)*count+1;
    char tmp[tmp_len];
    а у вас работает верно и без этих вычислений
    т.е. просто char tmp[n];

    Код (Text):
    #include <iostream>
    using namespace std;
    char * del_char(char *s, char *temp, char c){
    char *p=temp;
    int i=0,j=0;
    while(s[i]!='\0'){
    if(s[i]!=c) p[j++]=s[i];
    i++;}
    p[j]='\0';
    return p;}

    int main(){
    int n=100;
    char s[n];
    char d='p';
    cout<<"vvedite stroku"<<endl;
    cin.getline(s,n);
    cout<<s<<endl;
    int count=0;
    char* r; for(r=s;r=strchr(r,d);r+=sizeof(d))++count;
    unsigned int tmp_len=strlen(s)-sizeof(d)*count+1;
    char tmp[tmp_len];

    del_char(s,tmp,d);
    cout<<tmp<<endl;
    return 0;}
     
  9. shisik

    shisik Well-Known Member

    Регистрация:
    26 авг 2007
    Сообщения:
    154
    Симпатии:
    0
    Строки в C/C++ устроены таким образом, что обрабатываются до первого вхождения символа '\0', т.е. если строка определена как char str[256]; и в неё записать строку "Hello", то получится
    Код (Text):
    str[0] = 'H';
    str[1] = 'e';
    str[2] = 'l';
    str[3] = 'l';
    str[4] = 'o';
    str[5] = '\0';
    а str[6] и до str[255] просто будут игнорироваться. Поэтому совсем необязательно знать точный размер строки, достаточно выделить для неё заведомо больше (в разумных пределах, конечно).

    И ещё одно. Советую в дальнейшем всегда стараться свой код форматировать, чтоб он легко читался. Я тоже вначале не обращал на это внимание. Но потом понял, что так даже самому мне легче работать, не говоря уже про окружающих...
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей