Форум программистов CODEBY.NET Хостинг в Беларуси — Active Technologies

Разработка бизнес сайтов

Нужны клиенты? Тогда сюда быстрее...
X   Сообщение сайта
(Сообщение закроется через 2 секунды)

Здравствуйте, гость ( Вход | Регистрация )




> удалить в строке Char заданный символ
tanil72
Вставить ник
сообщение 25:04:2008, 11:12
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 11
Регистрация: 7:04:2008
Пользователь №: 16 436



Репутация: - 0 +


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

CODE
#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[i]!='\0'){
if(s[i]!=c) p[i]=s[i];
else p[i]=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[i];cout<<endl;

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


Сообщение отредактировал tanil72 - 25:04:2008, 12:00
Причина редактирования: Установка тегов кода
Подняться вверх 
 
Сообщение #1
 
Новая тема 
Ответов (1 - 8)
grigsoft
Вставить ник
сообщение 25:04:2008, 11:31
Цитата Ответить 


Мегагуру
****

Группа: Модеры
Сообщений: 715
Регистрация: 15:11:2005
Пользователь №: 2 573



Репутация: - 6 +


А отлаживаться вас не учат? Давай я научу. Берешь листик бумаги и ручку, записываешь в строчку имена локальных переменных, палец левой руки ставишь на первую строчку функции, правой записываешь под именами начальные значения. Теперь делаешь шаг левой рукой вниз на одну строчку, правой записываешь изменившиеся переменные. Продолжать пока реальные значения переменных не станут отличаться от ожидаемых. В результате даже без компьютера находишь ошибки у себя в программе. Заодно начинаешь понимать что же собственно у тебя написано.
Подняться вверх 
 
Сообщение #2
tanil72
Вставить ник
сообщение 25:04:2008, 12:07
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 11
Регистрация: 7:04:2008
Пользователь №: 16 436



Репутация: - 0 +


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

Цитата(grigsoft @ 25:04:2008, 11:31 ) *
А отлаживаться вас не учат? Давай я научу. Берешь листик бумаги и ручку, записываешь в строчку имена локальных переменных, палец левой руки ставишь на первую строчку функции, правой записываешь под именами начальные значения. Теперь делаешь шаг левой рукой вниз на одну строчку, правой записываешь изменившиеся переменные. Продолжать пока реальные значения переменных не станут отличаться от ожидаемых. В результате даже без компьютера находишь ошибки у себя в программе. Заодно начинаешь понимать что же собственно у тебя написано.

Подняться вверх 
 
Сообщение #3
Dimmuborgir
Вставить ник
сообщение 25:04:2008, 13:50
Цитата Ответить 


Новенький
*

Группа: Программист
Сообщений: 61
Регистрация: 27:12:2007
Пользователь №: 14 492



Репутация: - 0 +


думаю, дело в алгоритме удаления.)
Код
if(s[i]!=c)  
  p[i]=s[i];
else  
  p[i]=s[i+1];

неверное услоиве. по этому условию сдвигается на единицу только символ стоящий после нужного. Необходимо как я понимаю сдвигать все символы находящиеся после заданного. Как это сделать, я думаю сами додумаетесь.
Подняться вверх 
 
Сообщение #4
shisik
Вставить ник
сообщение 25:04:2008, 15:18
Цитата Ответить 


Продвинутый
**

Группа: Новенький
Сообщений: 141
Регистрация: 26:08:2007
Из: Харьков
Пользователь №: 12 480



Репутация: - 2 +


Так всё работает smile.gif
Код
#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' в конец строки добавляет автоматически из строки исходной wink.gif

Сообщение отредактировал shisik - 25:04:2008, 15:24
Подняться вверх 
 
Сообщение #5
tanil72
Вставить ник
сообщение 25:04:2008, 16:15
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 11
Регистрация: 7:04:2008
Пользователь №: 16 436



Репутация: - 0 +


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

CODE
#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[i]!='\0'){
if(s[i]!=c) p[j]=s[i];
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;
}



Сообщение отредактировал European - 28:04:2008, 07:32
Подняться вверх 
 
Сообщение #6
shisik
Вставить ник
сообщение 25:04:2008, 16:39
Цитата Ответить 


Продвинутый
**

Группа: Новенький
Сообщений: 141
Регистрация: 26:08:2007
Из: Харьков
Пользователь №: 12 480



Репутация: - 2 +


Цитата(tanil72 @ 25:04:2008, 18:15 ) *
а первоначальный код подправлен, но он не все делает,
если, например, символ идет подряд 2 раза,
он один удаляет, а следующий такой же оставляет не удаленным.

Это потому, что алгоритм неправильный. Ошибка заключается в том, что в операторе
Код
if (s[i] != c)
   p[j]=s[i];
else
   p[j]=s[++i];
i++;j++;

не нужно писать else. Я имею ввиду, что ты принудительно смещаешь исходную строку на один символ и без всяких проверок записываешь этот символ в результат. Поэтому второе подряд вхождения оно и не удаляет. Собственно, если этот участок переписать
Код
if (s[i] != c)
   p[j++]=s[i];
i++;

то эта проблема должна решиться (извини, проверять сейчас как-то неохота).

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

а затем
Код
tmp=del_char(s,d);

Подняться вверх 
 
Сообщение #7
tanil72
Вставить ник
сообщение 28:04:2008, 13:17
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 11
Регистрация: 7:04:2008
Пользователь №: 16 436



Репутация: - 0 +


Спасибо. Это была ошибка в логике. else не нужно.
Я думала, что важно знать точно длину результирующей строки и поэтому вычисляла
Код
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];

Код
#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;}


Сообщение отредактировал European - 29:04:2008, 06:32
Подняться вверх 
 
Сообщение #8
shisik
Вставить ник
сообщение 28:04:2008, 13:34
Цитата Ответить 


Продвинутый
**

Группа: Новенький
Сообщений: 141
Регистрация: 26:08:2007
Из: Харьков
Пользователь №: 12 480



Репутация: - 2 +


Цитата(tanil72 @ 28:04:2008, 15:17 ) *
Я думала, что важно знать точно длину результирующей строки и поэтому вычисляла
Код
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];

Строки в C/C++ устроены таким образом, что обрабатываются до первого вхождения символа '\0', т.е. если строка определена как char str[256]; и в неё записать строку "Hello", то получится
Код
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';
str[5] = '\0';

а str[6] и до str[255] просто будут игнорироваться. Поэтому совсем необязательно знать точный размер строки, достаточно выделить для неё заведомо больше (в разумных пределах, конечно).

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


Быстрый ответ  Ответить  Новая тема 

> Быстрый ответ
Полужирный
Курсив
Подчеркнутый
Вставить изображение
Смайлики
Цитата
Код
 
 Отправлять уведомления об ответах на e-mail |  Включить смайлики |  Добавить подпись
   

 

RSS Текстовая версия Сейчас: 5:09:2008 - 13:53
с нами можно связаться по:
телефону: +375-(29)-632-60-67
e-mail:info@codeby.net