Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.68/34: Рейтинг темы: голосов - 34, средняя оценка - 4.68
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142

В заданном тексте вставить пробелы между буквами

02.07.2018, 21:15. Показов 7495. Ответов 30

Студворк — интернет-сервис помощи студентам
Добрый вечер всем. Как мне для данной проги учесть пробелы между буквами в строке? (функция space_between_letters) Со строкой я на Вы, поэтому прошу помощи с работою над нею:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
 
using namespace std;
 
enum Mask
{
    UPPER = 128,
    SPACE_BETWEEN_LETTERS = 64,
    NEWLINE = 32,
};
 
void uppercase(char str[]) {
    char* step = str;
    while (*step != '\0') {
        *step = toupper(*step); // позволяет сделать буквы заглавными
        ++step;
    }
}
 
void space_between_letters(char str[]) {
    // пробелы между буквами
 
 
 
 
 
}
 
 
 
 
 
 
 
void main() {
 
    unsigned char settings = 0;
    int user_choise;
    char *str = new char[254];
    strcpy(str, "Some text for test");
    settings = Mask::UPPER | Mask::SPACE_BETWEEN_LETTERS; // == user_choise
 
 
 
    if ((settings & Mask::UPPER) == Mask::UPPER) {
        uppercase(str);
    }
 
    if ((settings & Mask::SPACE_BETWEEN_LETTERS) == Mask::SPACE_BETWEEN_LETTERS) {
        space_between_letters(str);
    }
 
 
 
 
 
 
 
    cout << str << endl;
 
    delete[] str;
    system("pause");
}
Добавлено через 1 час 36 минут
Нарыл функцию isalnum(), которая проверяет, является ли символом то, что содержится в теле функции или нет, реализовал проверку, все дела и получилось, только теперь появляется помимо строки, которая вышла, строка, которая была. Что мне с этим делать? Сам код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
 
using namespace std;
 
enum Mask
{
    UPPER = 128,
    SPACE_BETWEEN_LETTERS = 64,
    NEWLINE = 32,
};
 
void uppercase(char str[]) {
    char* step = str;
    while (*step != '\0') {
        *step = toupper(*step); // позволяет сделать буквы заглавными
        ++step;
    }
}
 
void space_between_letters(char str[]) {
    // пробелы между буквами
    char* step = str;
    while (*step != '\0') {
        if (isalnum(*step))
        {
            cout << *step << " ";
        }
 
        ++step;
    }
 
 
 
 
}
 
 
 
 
 
 
 
void main() {
 
    unsigned char settings = 0;
    char user_choise; // isalnum(str) ? cout << ""; :  
    char *str = new char[254];
    strcpy(str, "Some text for test");
    settings = Mask::UPPER | Mask::SPACE_BETWEEN_LETTERS; // == user_choise
 
    if ((settings & Mask::UPPER) == Mask::UPPER) {
        uppercase(str);
    }
 
    if ((settings & Mask::SPACE_BETWEEN_LETTERS) == Mask::SPACE_BETWEEN_LETTERS) {
        space_between_letters(str);
    }
 
 
 
 
 
 
 
    cout << str << endl;
 
    delete[] str;
    system("pause");
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.07.2018, 21:15
Ответы с готовыми решениями:

Выделить в тексте лишние пробелы между словами
ЕЩе одна задачка из Павловской... Прошу помощи!!! Если вам лень решать всю задачу, то меня очень интересует второй пункт... Но буду рад...

В любом тексте между 3 и 4 словом вставить новое слово
Ребят,помогите пожалуйста,в работе со строками совсем не шарю. Задание:в любом тексте между 3 и 4 словом вставить новое слово(работать с...

В тексте вставить между словами вместо одного пробела запятую и пробел
Доброго времени суток! В С++ я полный ноль. Пытаюсь разобраться со строками. Не могу понять, как это реализовать. Вот что есть сейчас: ...

30
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
06.07.2018, 07:35  [ТС]
Студворк — интернет-сервис помощи студентам
Спасибо за ответ, понял getline: воспользуюсь им Я также спросил о том, как действует цикл в проге gru74ika, можете объяснить?

Добавлено через 1 минуту
insert, size(), at.. Кто они такие?
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
06.07.2018, 07:42
Цитата Сообщение от N0VY Посмотреть сообщение
insert, size(), at.. Кто они такие?
N0VY, это функции-члены библиотечного типа std::string (раз и два).
0
483 / 275 / 57
Регистрация: 08.10.2015
Сообщений: 1,190
06.07.2018, 10:09
Путаница из-за неправильного названия темы. Вместо "Как учесть пробелы между буквами" надо было написать " Как вставить пробелы между буквами".
1
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
06.07.2018, 12:01  [ТС]
Логика? Помогите вместо того, что-бы обсуждать несколько страниц подряд, как я неправильно написал название темы. Оно не было осмысленно: торопился. Пожалуйста.
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
06.07.2018, 12:48
Цитата Сообщение от N0VY Посмотреть сообщение
Логика?
Вообще-то, правила форума обязывают Вас давать своим темам вменяемые названия (см. п. 4.3). Равно как и внятно формулировать условие задачи (см. п. 4.7).
Так что, вместо того, чтобы огрызаться, можно было вежливо поблагодарить неравнодушных форумчан за советы и извиниться.

Цитата Сообщение от N0VY Посмотреть сообщение
торопился
Вы торопились - Вам некогда. Абы как обозвали тему, абы как сформулировали задачу. У Вас времени не нашлось. Почему у других людей должно быть время Вам помогать? Советую пересмотреть своё отношение.

Цитата Сообщение от N0VY Посмотреть сообщение
Помогите
Вам уже написали код. Он работает.

Добавлено через 2 минуты
Цитата Сообщение от N0VY Посмотреть сообщение
И это делается через битовые операции.
А это ещё зачем?
0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
06.07.2018, 13:09  [ТС]
Во-первых, я не огрызался, во-вторых, прошу прощения: виноват за название темы, в третьих, я кажется дал уже понятное условие того, что мне требуется и в четвёртых, у меня действительно не так много времени на программу: мне нужно сделать её и парочку других заданий, что-бы я мог приняться за курсовую.. А программу, которую Вы мне, собственно, и дали я не понимаю: пожалуйста, объясните мне принцип, по которому работает цикл в ней. А ссылки, которые Вы мне дали, я использовал, прочёл материал, но getline не работает (ну, исходя из неопытности моей) Вот то, что я пытался реализовать (ошибка преобразования string в char):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <conio.h>
#include <string>
 
using namespace std;
 
enum Mask
{
    UPPER = 128,
    LOWER = 64,
    SPACE_BETWEEN_LETTERS = 32,
    NEWLINE = 16,
};
 
void uppercase(char str[]) {
    char* step = str;
    while (*step != '\0') {
        *step = toupper(*step); // позволяет сделать буквы заглавными
        ++step;
    }
}
 
void lowercase(char str[]) {
    char* step = str;
    while (*step != '\0') {
        *step = tolower(*step);
        ++step;
    }
}
 
void space_between_letters(char str[]) {
    // пробелы между буквами
    char* step = str;
    while (*step != '\0') {
        if (isalnum(*step))
        {
            cout << " ";
        }
        ++step;
    }
}
void newline(char str[], int size) {
    // \n после текста
 
    str[size - 1] = '\n';
}
 
 
 
 
 
void main() {
    setlocale(0, "rus");
 
    unsigned char settings = 0;
    char user_choise = 0;
 
    int size;
    cout << "Введите размер строки: ";
    cin >> size;
 
    string str;
 
    system("cls");
 
    cout << "Введите саму строку: ";
    getline(cin, str);
 
 
    system("cls");
 
    cout << "Большие (U) или маленькие (L) буквы? \n Ваш выбор: ";
    cin >> user_choise;
 
    if (user_choise == 'U')
        settings = Mask::UPPER;
    else if (user_choise == 'L')
        settings = Mask::LOWER;
 
    system("cls");
 
    cout << "Ставить ли пробелы между буквами? \n Ваш выбор: ";
    cin >> user_choise;
    
    if (user_choise == 'Y')
        settings = Mask::SPACE_BETWEEN_LETTERS;
 
    system("cls");
 
    cout << "Ставить ли Enter (\\n) после текста? \n Ваш выбор: ";
    cin >> user_choise;
 
    if (user_choise == 'Y')
        settings = Mask::NEWLINE;
 
    system("cls");
 
 
 
 
    if ((settings & Mask::UPPER) == Mask::UPPER) {
        uppercase(str);
    }
 
    if ((settings & Mask::LOWER) == Mask::LOWER) {
        lowercase(str);
    }
 
    if ((settings & Mask::SPACE_BETWEEN_LETTERS) == Mask::SPACE_BETWEEN_LETTERS) {
        space_between_letters(str);
    }
 
    if ((settings & Mask::NEWLINE) == Mask::NEWLINE) {
        newline(str, size);
    }
    system("cls");
 
    cout << str << endl;
    
    delete[] str;
    system("pause");
}
0
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
06.07.2018, 13:32
Цитата Сообщение от N0VY Посмотреть сообщение
ошибка преобразования string в char
Так измени входной параметр на тип string, или передавай
C++
1
str.c_str();
Но метод возвращает константу: const char * поэтому для работы с такой строкой копирнуть в буфер надо будет.

Но если у тебя string, меняй на string и не парься
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
06.07.2018, 15:52
N0VY, ну, давайте, разберём всё пошагово. Итак, вот код функции:
C++
1
2
3
4
5
6
7
8
void add_spaces_between_letters(std::string & str)
{
    for (size_t i = 1, limit = str.size()*2-1; i < limit; i += 2)
    {
        if (i < str.size() && str.at(i) != ' ')
            str.insert(i, " ");
    }
}
Функция на вход принимает один параметр по имени str - строку библиотечного типа std::string. Передача внутрь функции происходит по ссылке (значок амперсанда - &), что означает, что наша функция будет работать с оригиналом строки, а не с копией1.

Далее, цикл. Первое, что мы видим - тип счётчика в цикле у нас size_t. Это библиотечный целочисленный беззнаковый тип. Почему size_t, а не unsigned int, читаем по ссылке. Так, стоп-стоп... А из-за чего весь сыр-бор? Зачем вообще для переменной-счётчика нам понадобился беззнаковый тип? Почему не просто какой-нибудь int? Ну так int же - знаковый! А разве может у нас количество итераций (витков цикла) быть, скажем, -1? Не может. То-то и оно. Вот поэтому и нужен нам беззнаковый тип2, чтобы явно отразить этот факт для тех, кто потом будет читать наш код.

Функция-член size возвращает размер строки. Таким образом, если мы хотим узнать размер строки str, нам просто надо написать str.size()

В перой секции цикла for у нас идёт объявление двух переменных - счётчика i типа size_t, и ограничителя limit типа size_t - для условия окончания цикла. Почему limit у нас равен str.size()*2-1? Давайте разбираться.

Представим себе совсем маленькую строку, например такую: "code". Нам нужно превратить её в "c o d e". Элементы в исходном массиве у нас будут иметь такие индексы:
C++
1
2
3
4
str[0] == 'c'
str[1] == 'o'
str[2] == 'd'
str[3] == 'e'
А вот после вставки пробелов, индексы элементов будут такими:
C++
1
2
3
4
5
6
7
str[0] == 'c'
str[1] == ' ' // пробел
str[2] == 'o'
str[3] == ' ' // пробел
str[4] == 'd'
str[5] == ' ' // пробел
str[6] == 'e'
Что мы имеем?
  1. Если размер строки 4, то индекс последнего элемента 3. Индекс последнего элемента всегда на 1 меньше, чем размер массива (строка - это тоже массив, массив символов).
  2. Если размер строки 4, то надо вставить 3 пробела, а значит конечная строка будет иметь размер 7. То есть, удвоенный исходный размер минус один. То есть, str.size()*2-1.

Идём дальше. Если вставлять пробелы после каждого символа, то между словами получится по два пробела, а нам этого не надо. Вот тут-то у нас и появляется оператор ветвления if внутри цикла, который не позволяет вставлять пробел перед пробелом. В условии ифа встречаем функцию-член at (см. тут и тут). А именно мы видим вот такую запись: str.at(i). Это более безопасный вариант записи str[i]. В случае выхода за пределы массива, функция-член at сгенерирует исключение std::out_of_range, в то время как operator[] не выполняет никаких проверок.

Функция-член insert (см. тут и тут) принимает два параметра: первый - это позиция, в которую будет произведена вставка, а второй параметр - это символ (или строку), который будет вставлен. То есть, запись str.insert(i, " "); означает следующее: в строке str вставить перед символом с индексом i строку " "

Вот, собственно, и всё.
_______________________________
1При передаче в функцию параметра по значению работа внутри функции ведётся не с оригиналом переданного параметра, а с его локальной копией.
2При использовании беззнаковых типов в качестве счётчиков цикла следует быть внимательным и не допускать того, что называется wrap around (обращение значения). Проблема актуальна при декременте счётчика. Подробнее см. в книге Стенли Липпмана и Барбары Му "Язык программирования C++. Базовый курс" (5 издание, стр. 68).
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
06.07.2018, 16:29
Лучший ответ Сообщение было отмечено N0VY как решение

Решение

Чтобы лучше понять, что происходит внутри функции, можно снабдить её вот такими диагностическими сообщениями (временно, просто для отладочных целей):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
 
void add_spaces_between_letters(std::string & str)
{
    for (size_t i = 1, limit = str.size()*2-1, step = 1; i < limit; i += 2)
    {
        std::cout << "Step " << step++ << ":\n";
        std::cout << "Now str.size() is: " << str.size() << "\n";
        std::cout << "Now index i is: " << i << "\n";
        std::cout << "Our string before inserting is:\n" << str << "\n";
        if (i < str.size() && str.at(i) != ' ')
        {
            std::cout << "We are inside if-branch now.\n";
            str.insert(i, " ");
            std::cout << "Our string after inserting is:\n" << str << "\n";
        }
        else
        {
            std::cout << "We are inside else-branch now.\n";
            std::cout << "We skip inserting, because str[i] is space character.\n";
        }
        std::cout << "\n";
    }
}
 
int main()
{
    std::string phrase;
    getline(std::cin, phrase);
    add_spaces_between_letters(phrase);
    std::cout << phrase;
}
Миниатюры
В заданном тексте вставить пробелы между буквами  
2
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
06.07.2018, 16:55
А вообще, конечно, я намудрил. Можно ещё проще сделать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
 
void add_spaces_between_letters(std::string & str)
{
    for (size_t i = 1; i < str.size(); i += 2)
        if (str.at(i) != ' ')
            str.insert(i, " ");
}
 
int main()
{
    std::string phrase;
    getline(std::cin, phrase);
    add_spaces_between_letters(phrase);
    std::cout << phrase;
}
1
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
07.07.2018, 08:34  [ТС]
Самое понятное объяснение, которое я когда-либо видел. Большое спасибо Вам, gru7rik! Благодарен
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.07.2018, 08:34

В произвольном тексте вставить между вторым и третьим словом новое слово
&quot;В произвольном тексте вставить между вторым и третьим словом новое слово.&quot; Помоги пожалуйста)) С коментариями если можно для...

Удалить все символы в строке, не являющиеся буквами и заменить множественные пробелы одним
Ребята,буду запредельно благодарен.

Между буквами в тексте вставить определенный символ
Вобщем задача такая, например есть тест &quot;Всем привет&quot; нужно после нажатия кнопки или даже в момент печатания сделать его таким: В*с*е*м...

Пробелы между буквами после копирования из Маткада в Опенофис!
после копирования из маткада в опенофис появляются пробелы между буквами, что никак не годится. Знаю, есть способ вручную уменьшать...

В заданном тексте удалить из текста пробелы
строки 1)Дана строка состоящая из слов, разделенных пробелами. Посчитать количество сдвоенных букв во ведённом тексте. 2)2. В заданном...


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

Или воспользуйтесь поиском по форуму:
31
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru