Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.98/50: Рейтинг темы: голосов - 50, средняя оценка - 4.98
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68

ф-ция реверса строки

14.05.2013, 10:51. Показов 12013. Ответов 110
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
был вчера на собеседовании, попросили написать ф-цию реверса строки (поменять местами 1й и последний символы, 2й и предпоследний и т.д.), но ф-ция должна принимать параметром указатель на char т.е. на начало строки и все. я там немного тупанул но написал, вот хочу узнать есть ли решение получше моего.
вот код (писал в Embarcadero RAD Studio (Borland)):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//ф-ция принимает указатель на массив char с символом окончания строки '\0'
//и производит реверс полученного массива
void TForm1::reverce(char *str)
{
    char* end_str = &str[0];
 
    while (*end_str != '\0') ++end_str;
    
    char  buf;
    while (end_str > str)
    {
        --end_str;
        buf      = *str;
        *str     = *end_str;
        *end_str = buf;
        ++str;  
    }
}
кто захочет проверить, выносим кнопку, лабел и эдит на форму и в ивент на клик кнопки пишем:
C++
1
2
3
4
5
AnsiString str = Edit1->Text.c_str();
 
    reverce(str.c_str());
 
    Label1->Caption = str;
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.05.2013, 10:51
Ответы с готовыми решениями:

Функция реверса строки
На собеседовании в одну компанию меня попросили на бумажке написать функцию реверса строки. Буквально парой дней раньше я услышал о том...

Написание программы реверса строки
Не могу понять в чем ошибка выдаёт (2 3 3 3 3 3 3 3 3 3) Прошу помощи в нахождении ошибки. #include "stdafx.h" #include...

Какая ф-ция в VC++ определяет длину строки???
Здравствуйте ... не могу разобраться со строками в VC++ помогите пожалуйста

110
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
15.05.2013, 13:34
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от igor001 Посмотреть сообщение
да епт как? опиши действия машины последовательно?
-указатель str смотрит на начало сегмента
-по адресу на который смотрит указатель лежит ноль (терминатор, строка пустая)
-мы пытаемся вычислить длину - цикл подсчета не запускается ни разу потому как мы сразу видим что по адресу на который смотрит end_str лежит ноль - end_str остается указывающим на начало строки
-мы входим в условие цикла перестановки и делаем декремент перед сравнением
-end_str понижается ниже сегмента и система присваивает ему значение соответствующее верху сегмента
-условие выполняется end_str > str и мы входим в цикл
-мы переставляем ВСЕ содержимое сегмента до тех пор пока не дойдем до второго от начала строки символа - в этом случае условие --end_str > str не выполнится так как обратиться в равенство и мы выйдем из цикла (если машина к тому времени будет жива)
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.05.2013, 13:36
vxg, Все, что между " " является строковым литералом. Его тип (говорим сейчас об обычных символах и без конкатенации строк) является const char[n], где n - кол-во символов + '\0' ("qwerty" имеет тип const char[7]), расположенном в статической памяти программы (литерал существует все время работы программы). Если мы присваиваем его адрес к char* - мы имеем полное право менять символы, на которые указывает данный char*, однако если мы попытаемся изменить строковый литерал (НАСТОЯЩУЮ константу) - мы получим UB. Если мы сразу присвоим к const char*, при попытке изменения нас пошлет компилятор и мы не будем ловить клевые ошибки, если мы сразу присвоим к массиву (сделаем КОПИЮ строкового литерала) - мы можем его менять как хотим.
0
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
15.05.2013, 13:36
вот так работает
C++
#include <iostream>
#include <cstdio>
#include <string>
using namespace std ;
int main ()
{
string str ("text" ) ;
string buf = str ;
int len = str. size () ;
for (int i = 0 ; i < len ; i ++ )
{
    str [ i ] = buf [ len - 1 - i ] ;
}
cout << str << endl ;
}
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.05.2013, 13:39
programina, Конечно, ведь при создании строки происходит копия char* переданного в конструктор.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.05.2013, 13:39
Цитата Сообщение от vxg Посмотреть сообщение
всю жизнь спокойно присваивал указателю значение заключенное в кавычки при инициализации
Инициализация - пожалуйста. Изменять такую строку нельзя.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
15.05.2013, 13:39
Цитата Сообщение от ForEveR Посмотреть сообщение
мы получим UB
задам тупой вопрос - почему? "qwerty" лежит в блоке недоступном для записи?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.05.2013, 13:41
Цитата Сообщение от vxg Посмотреть сообщение
"qwerty" лежит в блоке недоступном для записи?
В том числе может быть и такое. Зависит от реализации.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.05.2013, 13:41
vxg, impl-defined.
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-
defined. The effect of attempting to modify a string literal is undefined.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
15.05.2013, 13:48
Цитата Сообщение от ForEveR Посмотреть сообщение
Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-
defined. The effect of attempting to modify a string literal is undefined.
типа данные могут храниться в части файла программы отображенной в память только для чтения? в шоке... а почему они вообще разрешают в таком случае это присвоение?? я то по наивности в каком-то проекте делал что то вроде
C++
1
char *s = "YYYY MM DD HH mm ss";
специально резервируя тем самым область для впечатывания на место "хлама" реальных значений (выводил в s).... *рвет на себе волосы*
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 13:48  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
-указатель str смотрит на начало сегмента
-по адресу на который смотрит указатель лежит ноль (терминатор, строка пустая)
-мы пытаемся вычислить длину - цикл подсчета не запускается ни разу потому как мы сразу видим что по адресу на который смотрит end_str лежит ноль - end_str остается указывающим на начало строки
-мы входим в условие цикла перестановки и делаем декремент перед сравнением
-end_str понижается ниже сегмента и система присваивает ему значение соответствующее верху сегмента
-условие выполняется end_str > str и мы входим в цикл
-мы переставляем ВСЕ содержимое сегмента до тех пор пока не дойдем до второго от начала строки символа - в этом случае условие --end_str > str не выполнится так как обратиться в равенство и мы выйдем из цикла (если машина к тому времени будет жива)
мы не входим ни в один цикл т.к. в 1м цикле по указателю не символ а литеральный ноль, во 2м - указатели равны
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
15.05.2013, 13:55
о... нашел. скрипт проекта для WinCC
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char *get_x(char x, char *name)
{
    static char *s = "xx_xxx";
 
    char *p = s + 3;
 
    s[0] = name[0];
    s[1] = x;
    name += 3;
    while (*name)
        *p++ = *name++;
    *p = '\0';
 
    return s;
}
потенциальный UB?

Добавлено через 4 минуты
Цитата Сообщение от igor001 Посмотреть сообщение
кто
C++
1
2
3
4
5
6
7
8
9
10
11
void reverse(char *str)
{
    if(!str) return; //у нас ненулевой указатель мы проходим это условие
 
    char* end_str = str; //теперь хвост равен началу
 
    while (*end_str) ++end_str; //мы не входим в этот цикл потому что символ лежащий по адресу хвоста - терминатор
 
    while (--end_str > str) //ЕСЛИ хвост стоит на начале сегмента, то, получив декремент он станет равным концу сегмента и мы войдем в цикл
    {...}
}
?
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
15.05.2013, 13:58
Цитата Сообщение от igor001 Посмотреть сообщение
я имел в виду что в случае пустой строки указатель end_str будет указывать на ячейку памяти перед символом окончания строки, т.е. туда, где был бы 1й символ строки
я имел в виду код из этого сообщения
там указатель будет установлен на str[-1] элемент, потому что не рассматривается случай, когда в строке нет символов
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
15.05.2013, 14:02
vxg, Самый что ни на есть UB в С++. Он даже не потенциальный.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.05.2013, 14:05
Цитата Сообщение от vxg Посмотреть сообщение
потенциальный UB?
даже если будет массив, нет никакой проверки на длину name, что в итоге может переполнить массив.
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,476
15.05.2013, 14:06
Цитата Сообщение от ForEveR Посмотреть сообщение
Самый что ни на есть UB
ох... век живи век учись
Цитата Сообщение от Tulosba Посмотреть сообщение
в итоге может переполнить массив
нет. там система так построена что поступающие в функцию имена гарантированно не могут выйти за пределы предполагаемого размера.
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 14:14  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
я имел в виду код из этого сообщения
там указатель будет установлен на str[-1] элемент, потому что не рассматривается случай, когда в строке нет символов
указывает, и что? мы ведь в цикл не войдем, указатель нигде далее не используется, хотя конечно конструкция опасная, согласен

Добавлено через 6 минут
хотя она опасная лишь в том случае, если после сдвига указателя на конец строки он по памяти перейдет за указатель на начало строки
0
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
16.05.2013, 19:02
ВООООООООООООТ ))))))))))))))))
C++
#include <iostream>
#include <string.h>
using namespace std;
 
 
char *reverse(char *s)
{
    int l = strlen(s);
 
    char b[l];
    
    for(int i=0; i < l; i++)
        b[i] = s[i];
 
    for(int i=0; i < l; i++)
        s[i] = b[l-1-i];
        
    return s;
}
 
 
int main()
{
    char s[] = "abcdefghijklmnopqrstuvwxyz";
    
    cout << reverse(s) << endl;
}
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
16.05.2013, 19:24
programina, не эффективно. И variable length array требуется.
0
Кактус
 Аватар для eocron
67 / 67 / 19
Регистрация: 23.05.2012
Сообщений: 342
16.05.2013, 19:41
10 страниц комментариев вокруг обычно реверса )) Я конечно еще кибер-титьку посасываю, но это по моему просто катастрофа )) Тут решений кушай не хочу, можно даже свой стринг написать таким образом, что сложность реверса будет O(1), а отличаться от обычного он будет разве, что названием и архитектурой, можно темплейт привязать, тогда крути-верти, что хочешь и так далее.
0
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
16.05.2013, 19:42
Цитата Сообщение от Tulosba Посмотреть сообщение
не эффективно. И variable length array требуется
Это все можно оставить, главное что работает, а вот с русскими буквами не работает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.05.2013, 19:42

Программа реверса строки: почему на экран выводится мусор, вместо нужного текста?
Пишу программу реверса строки (меняет местами первый символ и последний, второй и предпоследний и т.д.). На экран выводится мусор, вместо...

Защита от реверса ( md5 )
Люди посоветуйте как сделать проверку по md5 файла. Всё работает, НО. Я когда считаю хэш и вставляю его в исходники, хэш уже билда сразу...

Реализация реверса массива
Первый и последний элемент массива трогать не надо. Как его толком перевернуть? По-разному пробовал уже, не хотят циферки по серединке...

Защита от реверса проекта
Подскажите, в какую сторону копать, хочу, чтобы программа не могла быть запущена в отладчике?

Ошибка в создании реверса массива
#include &lt;iostream&gt; #include &lt;Windows.h&gt; #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; #include &lt;time.h&gt; using namespace std; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru