Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
OverDozero
99 / 99 / 6
Регистрация: 07.04.2011
Сообщений: 523
#1

Равномерное дополнение строки пробелами - C++

16.07.2014, 19:09. Просмотров 1626. Ответов 15
Метки нет (Все метки)

Всем доброго времени суток.Имеется задача:
Дан текст из нескольких строк. Написать функцию, равномерно дополняющую строку пробелами до определенной длины и с ее помощью отформатировать этот текст.
В программе должны быть функции
- ввода текста (из нескольких строк);
- вывода текста на экран;
- форматирования строки текста в соответствии с заданием.
Подскажите КАК следует понимать условие задачи?Что значит РАВНОМЕРНО дополнить строку пробелами до нужной длины?
Это так:
Нужна строка из 10 символов.У меня слово из 6.Это дополнить ее так:__ПРИМЕР__
или так:_П_Р_И_МЕР
Как на ваш взгляд,уважаемые форумчане,следует понимать условие задачи?
Спасибо за ответ
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.07.2014, 19:09     Равномерное дополнение строки пробелами
Посмотрите здесь:

Дополнение char строк пробелами при записи их в файл - C++
Пытаюсь написать простенькую прогу, создающую базу данных имен и номеров сотрудников в файле. Столкнулся со следующей проблемой: при записи...

Заданы 2 строки, состоящие из слов, разделенных пробелами. Определить местоположение символа первой строки - C++
Заданы 2 строки, состоящие из слов, разделенных пробелами. Определить местоположение символа первой строки, который первым не совпал с...

Заданы 2 строки, состоящие из слов, разделенных пробелами. Приписать три символа второй строки к первой - C++
Заданы 2 строки, состоящие из слов, разделенных пробелами. Приписать три символа второй строки к первой. Поменять местами в измененной...

Ввод строки с пробелами - C++
Собственно вот текст, не хочет никакими функциями принимать строку stud.fio с пробелами, испробовал всё, до чего голова дошла. Нужно чтобы...

Ввод строки с пробелами - C++
Знающие, помогите решить такую проблему. Надо составить маленькую программку, представление аудио-коллекции, в общем дело не сложное ,...

Ввод строки с пробелами - C++
нижеприведенный код получает строку до первого пробела, а нужно получать с учетом всех символов, что были введены. хелп, гайз. ...

Парсинг строки с пробелами - C++
Вообщем на выходе всего я получаю вот это : Вот сам файл script.csx: script dadada по идеи должно написать:

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IrineK
Заблокирован
16.07.2014, 19:28     Равномерное дополнение строки пробелами #2
Откройте Word
Выберите значение свойства "Выравнивание" - "по ширине"
Напишите несколько строк

То, что получится, и есть форматирование срок за счёт равномерного дополнения пробелами.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
16.07.2014, 19:53     Равномерное дополнение строки пробелами #3
Вот похожая задача.
OverDozero
99 / 99 / 6
Регистрация: 07.04.2011
Сообщений: 523
18.07.2014, 20:34  [ТС]     Равномерное дополнение строки пробелами #4
Получилось что-то типа такого:
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
 
 
// возвращает последний пробел в строке str, начиная с позиции start, если пробелов больше нет то -1
int get_last_space( char *str, int start )
{
    for ( int i = start; str[i]; ++i )
        if ( str[i] == ' ' )
            if ( str[i + 1] != ' ' )
                return i + 1;
            
    return -1;
}
 
// вставляет пробел в строку str, в позицию pos
void insert_space( char *str, int pos )
{
    int len = strlen(str);
    
    str[len + 1] = '\0'; // признак конца строки
    for ( int i = len; i > pos; --i )
        str[i] = str[i - 1];        
    str[pos] = ' ';
}
 
// дополняет стоку пробелами
void format_string(char *str, unsigned int len )
{
    int pos = 0;
    
    if ( get_last_space(str, 0) == -1 ) // если пробелов нет, ничего не делаем
        return;
 
    while ( strlen(str) < len ) // пока длина строки не достигнет нужного размера
    {
        pos = get_last_space(str, pos); // получаем пробел с позиции pos
        
        if ( pos != -1 ) // пока не достигнут конец строки, вставляем пробелы
        {
            insert_space(str, pos); 
            pos += 1;
        }
        else // иначе начнаем с начала строки
            pos = 0;
    }
}
 
int main( )
{
    int i;
    int n = 50;  // будем дополнять пробелими до длины n
    char s[256];
    
    printf("Enter string: "); // ввод строки
    gets(s);
 
    
    for ( i = 0; i < n; ++i )
        printf("-");
 
    format_string(s, n); // форматирование
    
    printf("\n%s\n", s); // вывод строки
    
    for ( i = 0; i < n; ++i )
        printf("-");
    
    getch();
    
    return 0;
}
Такой вопрос:
Как сделать,чтобы вводился текст из нескольких строк разделенных энтером.И заканчивался нажатием на esc
Например:
Привет_тут энтер
Мир_тут энтер
!_Тут esc и ввод закончился
Не получается сделать массив строк,с передачей их функцию.То есть функция должны вывести каждую строку отдельно,предварительно отформатировав ее таким образом как в коде.Но код форматирует только 1 строку.Не выходит сделать форматирование нескольких строк
Спасибо за советы!
Kerry_Jr
Модератор
Эксперт PHP
2180 / 1976 / 689
Регистрация: 14.05.2014
Сообщений: 5,774
Записей в блоге: 1
Завершенные тесты: 5
18.07.2014, 21:00     Равномерное дополнение строки пробелами #5
Цитата Сообщение от OverDozero Посмотреть сообщение
C++
1
2
int len = strlen(str);
str[len + 1] = '\0';
А для чего так делать?
OverDozero
99 / 99 / 6
Регистрация: 07.04.2011
Сообщений: 523
18.07.2014, 23:18  [ТС]     Равномерное дополнение строки пробелами #6
Ребят,как присвоить строке массива значение переменной,содержащей строку:
C++
1
2
3
4
5
6
7
8
9
    int i=0;
 
    char s[256];
    char strArr[999][256];
    printf("Enter string: ");
     while (getch()!=27){
      gets(s);
//вот тут тупик.как присвоить массиву значение переменной s?
i++;
Мне надо в дальнейшем передавать массив в функцию построчно.
Ps.Нет другого способа определить нажатие клавиши esc?У меня выходит по 2 нажатия на клавишу,после нажатия энтер.Вроде как ожидание нажатия клавиши.
Спасибо!
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
19.07.2014, 01:49     Равномерное дополнение строки пробелами #7
OverDozero, я так понял задача состоит в выравнивании строк?
С этого:
Какой-то неформатированный текст
с переносом на
другую строку
НА это: [_ - пробел]
Какой-то неформатированный текст
с_________переносом__________на
другую___________________строку
Все верно?
rikimaru2013
C++ Game Dev
2420 / 1114 / 240
Регистрация: 30.11.2013
Сообщений: 3,661
19.07.2014, 04:23     Равномерное дополнение строки пробелами #8
Цитата Сообщение от OverDozero Посмотреть сообщение
Как сделать,чтобы вводился текст из нескольких строк разделенных энтером.И заканчивался нажатием на esc

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
#include <iostream>
#include <conio.h>
 
using namespace std;
 
void main()
{
    
    char strArr[20][256] = {};
    for(int i=0;i<20;i++)
        strArr[i][0] = '\n';
 
    cout << "Enter strings: " << endl;
    int i =0;
    bool flag = true;
     while (true)
     {
         
            switch(int k = getch() ) // тут ждёт ввода с клавиатуры, если Esc то завершает вечный цикл, если нет то записываем и отрабатываем код после switch
            {
            case 27: flag = false; break;
            default: 
                cout << "--->  ";
                cout << (char)k;
                strArr[i][0] = k;
                gets(strArr[i]+1);
            }
         
        
        
        i++;
        if(flag == false)
            break;
    }
 
    cout << endl << endl;
 
    for(int i=0;i<20;i++)
    {
        if(strArr[i][0] != '\n')
        {
            cout << strArr[i];
            cout << endl;
        }
    }
 
}
OverDozero
99 / 99 / 6
Регистрация: 07.04.2011
Сообщений: 523
19.07.2014, 05:45  [ТС]     Равномерное дополнение строки пробелами #9
Цитата Сообщение от QGuest Посмотреть сообщение
OverDozero, я так понял задача состоит в выравнивании строк?
С этого:
Какой-то неформатированный текст
с переносом на
другую строку
НА это: [_ - пробел]
Какой-то неформатированный текст
с_________переносом__________на
другую___________________строку
Все верно?
Да вот непонятно .В условии задачи не сказано что надо переносить строку,и я сделал просто равномерное дополнение пробелами до определенной длины
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
19.07.2014, 10:40     Равномерное дополнение строки пробелами #10
Цитата Сообщение от OverDozero Посмотреть сообщение
Да вот непонятно .В условии задачи не сказано что надо переносить строку,и я сделал просто равномерное дополнение пробелами до определенной длины
Надо оценить требуемую сложность задачи. Просто заполнить строку пробелами слишком просто.
OverDozero
99 / 99 / 6
Регистрация: 07.04.2011
Сообщений: 523
19.07.2014, 13:52  [ТС]     Равномерное дополнение строки пробелами #11
Цитата Сообщение от QGuest Посмотреть сообщение
Надо оценить требуемую сложность задачи. Просто заполнить строку пробелами слишком просто.
Глядя на данное условие в голову приходит пословица:каков вопрос-таков ответ.
Условие поставлено некорректно,нет точной формулировки задачи.В частности перенос длинной строки.Сказано в условии дополнить-дополняю равномерно пробелами.Строка длиннее заданной длины-просто вывожу дальше.

Такой вот еще вопрос:почему в коде
C++
1
2
3
    printf("Enter string: ");
     while (getch()!=27)
      gets(s[k++]);
программа ожидает ЕЩЕ 1 нажатие клавиши?
Допустим запустил программу.Хочу ввести некоторый текст.Начинаю вводить
Привет
Мир
!
Но перед началом ввода слова после запуска,и после нажатия на энтер необходимо нажать еще раз любую клавишу?То есть получается перед вводом первого слова я должен нажать 2 раза букву "П",чтобы получить первую букву "П".Для ввода текста из примера выше надо набирать так:
ППривет_тут энтер
ММир_тут энтер
!!_тут энтер и esc
Почему программа ждет 2 нажатия перед вводом и после нажатия энтера?
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
 
 
// âîçâðГ*Г№Г*ГҐГІ ïîñëåäГ*ГЁГ© ïðîáåë Гў ñòðîêå str, Г*Г*Г·ГЁГ*Г*Гї Г± ïîçèöèè start, åñëè ïðîáåëîâ áîëüøå Г*ГҐГІ ГІГ® -1
int get_last_space( char *str, int start )
{
    for ( int i = start; str[i]; ++i )
        if ( str[i] == ' ' )
            if ( str[i + 1] != ' ' )
                return i + 1;
            
    return -1;
}
 
// ГўГ±ГІГ*âëÿåò ïðîáåë Гў ñòðîêó str, Гў ïîçèöèþ pos
void insert_space( char *str, int pos )
{
    int len = strlen(str);
    
    str[len + 1] = '\0'; // ïðèçГ*Г*ГЄ ГЄГ®Г*Г¶Г* ñòðîêè
    for ( int i = len; i > pos; --i )
        str[i] = str[i - 1];        
    str[pos] = ' ';
}
 
// äîïîëГ*ГїГҐГІ ñòîêó ïðîáåëГ*ìè
void format_string(char *str, unsigned int len )
{
    int pos = 0;
    
    if ( get_last_space(str, 0) == -1 ) // åñëè ïðîáåëîâ Г*ГҐГІ, Г*ГЁГ·ГҐГЈГ® Г*ГҐ äåëГ*ГҐГ¬
        return;
 
    while ( strlen(str) < len ) // ïîêГ* äëèГ*Г* ñòðîêè Г*ГҐ äîñòèãГ*ГҐГІ Г*ГіГ¦Г*îãî Г°Г*çìåðГ*
    {
        pos = get_last_space(str, pos); // ïîëó÷Г*ГҐГ¬ ïðîáåë Г± ïîçèöèè pos
        
        if ( pos != -1 ) // ïîêГ* Г*ГҐ äîñòèãГ*ГіГІ ГЄГ®Г*ГҐГ¶ ñòðîêè, ГўГ±ГІГ*âëÿåì ïðîáåëû
        {
            insert_space(str, pos); 
            pos += 1;
        }
        else // ГЁГ*Г*Г·ГҐ Г*Г*Г·Г*Г*ГҐГ¬ Г± Г*Г*Г·Г*Г«Г* ñòðîêè
            pos = 0;
    }
}
 
int main( )
{
    int i=0;
    int k=0;
    int n = 50;  // áóäåì äîïîëГ*ГїГІГј ïðîáåëèìè äî äëèГ*Г» n
    char s[999][255];
 
    printf("Enter string: "); // ââîä ñòðîêè
     while (getch()!=27)
      gets(s[k++]);
        
    for ( i = 0; i < n; ++i )
        printf("-");
        printf("\n");
        
for ( i = 0; i < k; ++i ){
    format_string(s[i], n); // ôîðìГ*òèðîâГ*Г*ГЁГҐ
    
    printf("%s\n", s[i]); // âûâîä ñòðîêè
}
    
    for ( i = 0; i < n; ++i )
        printf("-");
    
    getch();
    
    return 0;
}
rikimaru2013
C++ Game Dev
2420 / 1114 / 240
Регистрация: 30.11.2013
Сообщений: 3,661
19.07.2014, 15:36     Равномерное дополнение строки пробелами #12
Цитата Сообщение от OverDozero Посмотреть сообщение
Почему программа ждет 2 нажатия перед вводом и после нажатия энтера?

Цитата Сообщение от OverDozero Посмотреть сообщение
printf("Enter string: ");
* * *while (getch()!=27)
* * * gets(s[k++]);
1. Выводит текст
2. Ждёт нажатие любой клавиши без ентера.
3. Что нажали в int представлении сравнивает с числом 27. Если не 27 идёт дальше.
4. Ждёт ввода с клавиатуры. Всё, что нажато до Enter записывается в переданный буфер.

5. Ждёт нажатие любой клавиши без ентера.
6. Что нажали в int представлении сравнивает с числом 27. Если не 27 идёт дальше.
7. Ждёт ввода с клавиатуры. Всё, что нажато до Enter записывается в переданный буфер.

В 3 и 6 пунктах после нажатия пользователем программа создаёт литерал, сравнивает его с числом 27 и забывает про этот литерал. Он никуда не записывается, негде дальше не используется. Забыли про него. Точка.
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
19.07.2014, 15:48     Равномерное дополнение строки пробелами #13
Цитата Сообщение от OverDozero Посмотреть сообщение
программа ожидает ЕЩЕ 1 нажатие клавиши?
Надо вот так:
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
#include <iostream>
#include <conio.h>
#include <string>
 
using namespace std;
 
 
string read_string_while_not(int end) {
    string result = "";
    char symbol = 0;
    while(true) {
        //Читаем символ
        symbol = _getch();
        
        //Выводим на экран и добавляем до строки, если это не стоп-символ
        if (symbol != end) {
            if (symbol == 13) {
                cout << "\n";
                result += "\n";
            }
            else {
                cout << symbol;
                result += symbol;
            }
        }
        //В ином случае останавливаем чтение
        else break;
    };
 
    return result;
}
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
19.07.2014, 16:25     Равномерное дополнение строки пробелами #14
Вот готовое решение.
Полною работоспособность не гарантирую, нужно еще хорошенько все проверить, но вроде работает:

Вот файл:
Formatter.txt

Пример:
Равномерное дополнение строки пробелами

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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iostream>
#include <string>
#include <vector>
#include <conio.h>
 
using namespace std;
 
class Formatter {
private:
 
    //Расделяет строку на вектор слов (взято с интернета :) )
    static vector<string> split(string data, string delimiters) {
        vector<string> parts;
 
        string::size_type lastPos = data.find_first_not_of(delimiters, 0);
        string::size_type pos = data.find_first_of(delimiters, lastPos);
        while (string::npos != pos || string::npos != lastPos) {
            parts.push_back(data.substr(lastPos, pos - lastPos));
            lastPos = data.find_first_not_of(delimiters, pos);
            pos = data.find_first_of(delimiters, lastPos);
        }
 
        return parts;
    }
 
    //Парсит (разбирает) текст на вектор с векторов слов
    static vector<vector<string>> parse(string data) {
        vector<vector<string>> result;
        vector<string> splited = split(data, "\n");
        for (int i = 0; i < splited.size(); i++) {
            result.push_back(split(splited[i], " "));
        }
        return result;
    }
 
    //Вычисляет длину вектора слов
    static int getLineLength(vector<string> data) {
        int result = 0;
        for (int i = 0; i < data.size(); i++) result += data[i].length();
        return result;
    }
 
    //Вычисляет максимальную длину вектора слов
    static int getMaxLength(vector<vector<string>> data) {
        int max = 0;
        for (int i = 0; i < data.size(); i++) {
            int lineLength = getLineLength(data[i]) + data[i].size() - 1;
            if (max < lineLength) max = lineLength;
        }
        return max;
    }
 
    //Возвращает сторку с пробелами определенной длины
    static string getSpaces(unsigned int count) {
        string result = "";
        for (int i = 0; i < count; i++) result += ' ';
        return result;
    }
 
    //Вычисляет нужное количество пробелов для вектора слов для определенной длины
    static vector<int> calculateSpaces(vector<string> data, int length) {
        if (data.size() == 1) {
            int spaces = length - data[0].length();
            return { spaces };
        }
 
        length -= data[data.size() - 1].length();
        data.erase(data.end() - 1);
 
        int count = length - getLineLength(data);
        vector<int> result;
        int cursor = 0;
        for (int i = 0; i < data.size(); i++) result.push_back(0);
        while (count > 0) {
            result[cursor]++;
            count--;
 
            if (cursor == data.size() - 1) cursor = 0;
            else cursor++;
        }
 
        return result;
    }
 
    //Возвращает готовую расширеную строку до длины length
    static string expandTo(vector<string> data, int length) {
        int lineLength = getLineLength(data);
        string result = "";
        vector<int> spaces = calculateSpaces(data, length);
 
        for (int i = 0; i < data.size() - 1; i++) {
            result += (data[i] + getSpaces(spaces[i]));
        }
        result += data[data.size() - 1];
        return result;
    }
 
public:
 
    //Главная функция форматирования
    static string format(string data) {
        vector<vector<string>> strings = parse(data);
        int max = getMaxLength(strings);
        string result = "";
 
        for (int i = 0; i < strings.size(); i++) {
            result += (expandTo(strings[i], max) + "\n");
        }
        return result;
    }
};
 
string readStringWhileNot(int end) {
    string result = "";
    char symbol = 0;
    while(true) {
        //Читаем символ
        symbol = _getch();
        
        //Выводим на экран и добавляем до строки, если это не стоп-символ
        if (symbol != end) {
            if (symbol == 13) {
                cout << "\n";
                result += "\n";
            }
            else {
                cout << symbol;
                result += symbol;
            }
        }
        //В ином случае останавливаем чтение
        else break;
    };
 
    return result;
}
 
int main() {
    cout << "Enter text: \n";
    string text = readStringWhileNot(27);
 
    cout << "\nFormatted text: \n" << Formatter::format(text);
    cin.get();
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2014, 20:43     Равномерное дополнение строки пробелами
Еще ссылки по теме:

Разделение строки пробелами - C++
Необходимо считать из файла слова, те что длинее MAX_LEN разделить пробелами на слова длиной NEW_LEN и менее, не могу найти ошибку в...

Считывание строки с пробелами - C++
Ситуация такая, необходимо с консоли прочитать строку вводимую пользователем вместе с пробелами. #include &lt;iostream&gt; using...

си, чтение строки из stdin с пробелами - C++
Доброго времени суток, Надо записать строку в char * str. scanf(&quot;%s&quot;,str) читает до пробела, gets срабатывает сразу при вызове,...

Чтение строки вместе с пробелами - C++
Всем привет. string str1;cin&gt;&gt;str1; int len1 = str1.length(); cout&lt;&lt;len1; string str1=&quot;Hello world&quot;; int len1 = str1.length(); ...

Ввод строки char с пробелами - C++
Всем доброго дня. Подскажите плз, У меня есть указатель char *str как ввести в него строку с пробелами которую ввел пользователь. Класс...


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

Или воспользуйтесь поиском по форуму:
Psilon
Master of Orion
Эксперт .NET
5883 / 4780 / 633
Регистрация: 10.07.2011
Сообщений: 14,405
Записей в блоге: 5
Завершенные тесты: 4
19.07.2014, 20:43     Равномерное дополнение строки пробелами #15
Насколько я понимаю условие задачи, нужно просто справа и слева строку дополнить пробелами, чтобы получилась длина N, а не вставлять пробелы между всеми словами с слове. Иначе слишком много проблем возникает: с юникодовскими символами-суррогатами, с табуляциями, переносами и т.п.
Yandex
Объявления
19.07.2014, 20:43     Равномерное дополнение строки пробелами
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru