Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как удалить символ из строки, из "Указатели, строки, классы и пр." 
:(
    Опции темы
Frekenbok
Дата 2.11.2006, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: нет
Всего: 1



У меня вопрос по строкам Си. Как удалить символ из строки? 
Допустим, есть char s[100]. Записываем в s строку "мама мыла раму". Как удалить 'ы'  именно в s? 
Можно так?:  поставить указатель на букву 'л' и сдвинуть весь хвост вместе с символом \0? Или можно только записать все в новую переменную без буквы 'ы' или сразу выводить на печать все, кроме 'ы'? 
Подскажите, пожалуйста...Можно с кодом... smile 
Может, где-то на форуме это уже было? Не могу найти smile 
PM MAIL   Вверх
ManiaK
Дата 2.11.2006, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Homo Sapience
***


Профиль
Группа: Комодератор
Сообщений: 1145
Регистрация: 3.8.2004
Где: ИУ5-93

Репутация: нет
Всего: 29



Цитата(Frekenbok @  2.11.2006,  14:56 Найти цитируемый пост)
Может, где-то на форуме это уже было?

Это слишком элементарно (!=тупо!).

Цитата(Frekenbok @  2.11.2006,  14:56 Найти цитируемый пост)
поставить указатель на букву 'л' и сдвинуть весь хвост вместе с символом \0?

Можно, почему же нет?

Код

char* p = &s[5];
while(*p++) *p = *(p+1);


Надо, конечно, пояснить. Внутри while сначала происходит извлечение значения, на которое указывает p ("*p") и проверка на равенство нулю. Если выражение нулю не равно, то происходит сдвиг указателя вперёд (инкремент, "p++") и выполнение тела цикла. После чего всё повторяется и до тех пор, пока выражение внутри while не станет равно нулю. Может такое подробное объяснение для тебя, Frekenbok, но для кого-то возможно будет полезно.

Вообще, компилятор всегда пытается преобразовать результат выражения внутри while к логическому типу; если результат отличен от нуля - true, если нет - false, поэтому писать *p != 0 не обязательно. Тоже касается и других условных конструкций (for, if, ..).

Цитата(Frekenbok @  2.11.2006,  14:56 Найти цитируемый пост)
Или можно только записать все в новую переменную без буквы 'ы' или сразу выводить на печать все, кроме 'ы'? 

И так тоже можно.

Это сообщение отредактировал(а) ManiaK - 7.11.2006, 15:13
PM MAIL WWW   Вверх
archimed7592
Дата 4.11.2006, 04:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: нет
Всего: 93



скорее
Код
char* p = &s[6];
while(*p++) *(p-1) = *p;
 smile 


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
ManiaK
Дата 7.11.2006, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Homo Sapience
***


Профиль
Группа: Комодератор
Сообщений: 1145
Регистрация: 3.8.2004
Где: ИУ5-93

Репутация: нет
Всего: 29



archimed7592, спасибо, действительно smile 
PM MAIL WWW   Вверх
Frekenbok
Дата 7.11.2006, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: нет
Всего: 1



А так я вставляю 'ы' обратно:
сдвигаю каждый символ с конца и до нужной позиции, а потом просто присваиваю 'ы'.
Код

 while (*p++); 
 while(p!=&s[5]) *(p+1) = *p--; 
   s[6]='ы'; 

Может, предложите еще какой-нибудь вариант получше?   smile 
PM MAIL   Вверх
Damarus
Дата 7.11.2006, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

Репутация: 6
Всего: 29



Цитата(ManiaK @  7.11.2006,  15:54 Найти цитируемый пост)
 Если размер строки вам заранее неизвестен, то вот эта инструкция на мой взгляд - самый быстрый способ оказаться в последнем символе.

Не совсем так. После такой инструкции p будет указывать на первый символ после завершающего ноля.

PM MAIL ICQ Jabber   Вверх
archimed7592
Дата 7.11.2006, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: нет
Всего: 93



Цитата(ManiaK @  7.11.2006,  16:54 Найти цитируемый пост)
for(p-=2; p-str != 6;) *p-- = *(p-1);
UB, 5.0/8

Это сообщение отредактировал(а) archimed7592 - 7.11.2006, 16:37


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
ManiaK
Дата 7.11.2006, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Homo Sapience
***


Профиль
Группа: Комодератор
Сообщений: 1145
Регистрация: 3.8.2004
Где: ИУ5-93

Репутация: нет
Всего: 29



Цитата(archimed7592 @  7.11.2006,  16:37 Найти цитируемый пост)
UB, 5.0/8

Это что значит?..

Цитата(Damarus @  7.11.2006,  16:24 Найти цитируемый пост)
Не совсем так. После такой инструкции p будет указывать на первый символ после завершающего ноля.

Угу, "рука дрогнула" smile
PM MAIL WWW   Вверх
archimed7592
Дата 7.11.2006, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: нет
Всего: 93



Цитата(ManiaK @  7.11.2006,  18:05 Найти цитируемый пост)
Это что значит?..
фу блин, 5/4
Цитата
Chapter 5 Expressions
4 Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

другими словами в выражении *p-- = *(p-1); неизвестно что произойдёт раньше - уменьшение p или вычисление (p-1)


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
maxim1000
Дата 7.11.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 1
Всего: 110



коротко не значит просто ;)
а простота и отсутствие ошибок сильно коррелируют...
Код

void InsertCharacter(char *buffer,char character,unsigned position)
{
    while(position>0 && *buffer!=0)
    {
        ++buffer;
        --position;
    }
    while(true)
    {
        char temp=*buffer;
        *buffer++=character;
        if(temp==0)
        {
            *buffer=0;
            break;
        }
        character=temp;
    }
}


Это сообщение отредактировал(а) maxim1000 - 7.11.2006, 18:18


--------------------
qqq
PM WWW   Вверх
Frekenbok
Дата 8.11.2006, 07:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: нет
Всего: 1



Цитата(ManiaK @  7.11.2006,  15:54 Найти цитируемый пост)

while(*p!=&s[5]) *(p+1) = *p--;
В общем виде это работать не будет. Ты проверяешь в цикле на равенство конкретному символу, а вдруг такой же символ будет ближе?

А может, проверка на равенство конкретному символу выглядит так: *p!=s[5]? Имелась в виду конкретная позиция 6, т.е. адрес &s[5].

Цитата(ManiaK @  7.11.2006,  15:54 Найти цитируемый пост)
for(p-=2; p-str != 6;) *p-- = *(p-1);

Хороший вариант, спасибо. Только последняя буква теряется. По-моему, надо так:
Код

for(p-=1; p-str != 6;) *p-- = *(p-1);


Добавлено @ 07:19 
Цитата(Damarus @  7.11.2006,  16:24 Найти цитируемый пост)
После такой инструкции p будет указывать на первый символ после завершающего ноля.

Смысл и был такой: поставить указатель после нуля и весь хвост сдвинуть на "один" адрес. Или со строками лучше такое не проделывать? Когда char s[100], а длина строки 20, наверное, ничего не будет. А если я выделяю памяти ровно столько, сколько нужно (char s[20]), может вылезти косяк при выходе за границы строки? Или нет?
Цитата(archimed7592 @  7.11.2006,  17:16 Найти цитируемый пост)
the behavior is undefined.

Вроде работает. Лучше не пользоваться такими выражениями (*p-- = *(p-1); )? Эта глава откуда?
PM MAIL   Вверх
Frekenbok
Дата 8.11.2006, 07:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: нет
Всего: 1



Maxim1000, спасибо за вариант, быд такой в голове, только руки не дошли... Скорее хотелось.

Цитата(maxim1000 @  7.11.2006,  18:16 Найти цитируемый пост)
while(position>0 && *buffer!=0)
    {
        ++buffer;
        --position;
    }

 А может, сразу...?
Код

buffer=*buffer[position];

Или так:
Код

buffer+=position;

PM MAIL   Вверх
archimed7592
Дата 8.11.2006, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: нет
Всего: 93



Цитата(Frekenbok @  8.11.2006,  08:10 Найти цитируемый пост)
Вроде работает.
ага. "вроде" smile мини-тест
Цитата(Frekenbok @  8.11.2006,  08:10 Найти цитируемый пост)
Лучше не пользоваться такими выражениями (*p-- = *(p-1); )?
точно. по крайней мере не факт, что после смены компилятора твой код будет работать так же.
Цитата(Frekenbok @  8.11.2006,  08:10 Найти цитируемый пост)
Эта глава откуда?
 smile из стандарта. вверху форума есть шапка "Правила форума С++:Общие вопросы", там первая ссылка как раз на эту великую "книгу" smile 


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
maxim1000
Дата 8.11.2006, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 1
Всего: 110



Цитата(Frekenbok @  8.11.2006,  06:28 Найти цитируемый пост)
А может, сразу...?

если есть гарантия того, что position < длины строки, то можно и сразу...

Добавлено @ 12:46 
Цитата(Frekenbok @  8.11.2006,  06:28 Найти цитируемый пост)
быд такой в голове, только руки не дошли... Скорее хотелось.

в том-то и дело, что часто мы склонны оценивать время только на написание программы, но не на отладку smile


--------------------
qqq
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0566 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.