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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.91
OverDozero
 Аватар для OverDozero
98 / 98 / 6
Регистрация: 07.04.2011
Сообщений: 517
16.07.2014, 19:09     Равномерное дополнение строки пробелами #1
Всем доброго времени суток.Имеется задача:
Дан текст из нескольких строк. Написать функцию, равномерно дополняющую строку пробелами до определенной длины и с ее помощью отформатировать этот текст.
В программе должны быть функции
- ввода текста (из нескольких строк);
- вывода текста на экран;
- форматирования строки текста в соответствии с заданием.
Подскажите КАК следует понимать условие задачи?Что значит РАВНОМЕРНО дополнить строку пробелами до нужной длины?
Это так:
Нужна строка из 10 символов.У меня слово из 6.Это дополнить ее так:__ПРИМЕР__
или так:_П_Р_И_МЕР
Как на ваш взгляд,уважаемые форумчане,следует понимать условие задачи?
Спасибо за ответ
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IrineK
Заблокирован
16.07.2014, 19:28     Равномерное дополнение строки пробелами #2
Откройте Word
Выберите значение свойства "Выравнивание" - "по ширине"
Напишите несколько строк

То, что получится, и есть форматирование срок за счёт равномерного дополнения пробелами.
Mr.X
Эксперт С++
 Аватар для Mr.X
2799 / 1575 / 246
Регистрация: 03.05.2010
Сообщений: 3,656
16.07.2014, 19:53     Равномерное дополнение строки пробелами #3
Вот похожая задача.
OverDozero
 Аватар для OverDozero
98 / 98 / 6
Регистрация: 07.04.2011
Сообщений: 517
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
Модератор
 Аватар для Kerry_Jr
1855 / 1651 / 575
Регистрация: 14.05.2014
Сообщений: 4,737
Записей в блоге: 1
Завершенные тесты: 5
18.07.2014, 21:00     Равномерное дополнение строки пробелами #5
Цитата Сообщение от OverDozero Посмотреть сообщение
C++
1
2
int len = strlen(str);
str[len + 1] = '\0';
А для чего так делать?
OverDozero
 Аватар для OverDozero
98 / 98 / 6
Регистрация: 07.04.2011
Сообщений: 517
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
 Аватар для rikimaru2013
2133 / 966 / 222
Регистрация: 30.11.2013
Сообщений: 3,231
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
 Аватар для OverDozero
98 / 98 / 6
Регистрация: 07.04.2011
Сообщений: 517
19.07.2014, 05:45  [ТС]     Равномерное дополнение строки пробелами #9
Цитата Сообщение от QGuest Посмотреть сообщение
OverDozero, я так понял задача состоит в выравнивании строк?
С этого:
Какой-то неформатированный текст
с переносом на
другую строку
НА это: [_ - пробел]
Какой-то неформатированный текст
с_________переносом__________на
другую___________________строку
Все верно?
Да вот непонятно .В условии задачи не сказано что надо переносить строку,и я сделал просто равномерное дополнение пробелами до определенной длины
QGuest
8 / 8 / 0
Регистрация: 08.01.2013
Сообщений: 85
19.07.2014, 10:40     Равномерное дополнение строки пробелами #10
Цитата Сообщение от OverDozero Посмотреть сообщение
Да вот непонятно .В условии задачи не сказано что надо переносить строку,и я сделал просто равномерное дополнение пробелами до определенной длины
Надо оценить требуемую сложность задачи. Просто заполнить строку пробелами слишком просто.
OverDozero
 Аватар для OverDozero
98 / 98 / 6
Регистрация: 07.04.2011
Сообщений: 517
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
 Аватар для rikimaru2013
2133 / 966 / 222
Регистрация: 30.11.2013
Сообщений: 3,231
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();
}
Psilon
Master of Orion
 Аватар для Psilon
5738 / 4686 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
19.07.2014, 20:43     Равномерное дополнение строки пробелами #15
Насколько я понимаю условие задачи, нужно просто справа и слева строку дополнить пробелами, чтобы получилась длина N, а не вставлять пробелы между всеми словами с слове. Иначе слишком много проблем возникает: с юникодовскими символами-суррогатами, с табуляциями, переносами и т.п.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2014, 11:03     Равномерное дополнение строки пробелами
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Krock21rus
73 / 73 / 19
Регистрация: 18.11.2013
Сообщений: 369
Завершенные тесты: 2
21.07.2014, 11:03     Равномерное дополнение строки пробелами #16
Моё мнение: мне кажется, что это означает сделать длину всех строк по 255, то есть изменить каждый символ '\0' на ' ', дерзайте
Yandex
Объявления
21.07.2014, 11:03     Равномерное дополнение строки пробелами
Ответ Создать тему
Опции темы

Текущее время: 03:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru