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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
harkonin
0 / 0 / 0
Регистрация: 20.06.2010
Сообщений: 19
#1

Функция доводит длину строки до заданной, вставляя пробелы между словами - C++

23.06.2010, 01:13. Просмотров 1618. Ответов 10
Метки нет (Все метки)

Помогите с прогой на С

Функция доводит длину строки до заданной, вставляя пробелы между словами
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.06.2010, 01:13     Функция доводит длину строки до заданной, вставляя пробелы между словами
Посмотрите здесь:
C++ Функция доводит длину строки до заданной, вставляя пробелы между словами
Довести длину строки до заданной, вставляя пробелы между словами C++
Написать программу, которая удаляет из текста пробелы между словами и записывает в массив N длину каждого слова C++
C++ Функция удаляет из строки пробелы и вставляет межу словами по 2 символа
C++ Функция, сравнивающая две строки, игнорируя количество пробелов между словами
C++ Убрать в текстовом файле ненужные пробелы, оставив между словами по одному, между предложениями по два.
C++ Пробелы между словами\предложениями
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
profu
2 / 2 / 0
Регистрация: 08.06.2010
Сообщений: 11
23.06.2010, 12:00     Функция доводит длину строки до заданной, вставляя пробелы между словами #2
А если сама строка состоит из одного слова всего? И что делать, как доводить ее до нужной длины?
harkonin
0 / 0 / 0
Регистрация: 20.06.2010
Сообщений: 19
23.06.2010, 15:38  [ТС]     Функция доводит длину строки до заданной, вставляя пробелы между словами #3
Если из одного слова(Т.Е. без пробелов) то ничего не делать(выдать сообщение про одно слово в строке), либо доставить пробелы до заданной длины. Помогите хоть как нибудь.
easybudda
Эксперт С++
9458 / 5471 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
23.06.2010, 17:39     Функция доводит длину строки до заданной, вставляя пробелы между словами #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
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct WRD {
    char * text;
    int len;
    struct WRD * next;
} wrd_t;
 
wrd_t * new_word(const char * s, wrd_t * last){
    wrd_t * w;
    if ( ( w = (wrd_t*)malloc(sizeof(wrd_t)) ) == NULL )
        return NULL;
    if ( ( w->text = strdup(s) ) == NULL ){
        free(w);
        return NULL;
    }
    w->len = strlen(w->text);
    w->next = NULL;
    if ( last )
        last->next = w;
    return w;
}
 
int words_len(const wrd_t * w){
    int len = 0;
    while ( w ){
        len += w->len;
        w = w->next;
    }
    return len;
}
 
void delete_words(wrd_t * w){
    wrd_t * t;
    while ( w ){
        t = w->next;
        free(w->text);
        free(w);
        w = t;
    }
}
 
char * justify(const char * s, const char * delim, int width){
    char * bufIn, * bufOut, * pBuf, * pWrd;
    int regular, extra, len, cnt, i;
    wrd_t * first, * last, * cur;
 
    if ( ( bufIn = strdup(s) ) == NULL )
        return NULL;
    cnt = 0;
    first = last = NULL;
    for ( pWrd = strtok(bufIn, delim); pWrd; pWrd = strtok(NULL, delim) ){
        if ( ( last = new_word(pWrd, last) ) == NULL ){
            if ( first )
                delete_words(first);
            return NULL;
        }
        if ( ! first )
            first = last;
        ++cnt;
    }
    free(bufIn);
 
    if ( ! first )
        return NULL;
    if ( cnt == 1 ){
        bufOut = strdup(first->text);
        delete_words(first);
        return bufOut;
    }
 
    len = words_len(first);
    if ( len + cnt - 1 > width ){
        bufOut = strdup("Too long!");
        delete_words(first);
        return bufOut;
    }
 
    if ( ( bufOut = (char*)malloc(width + 1) ) == NULL ){
        delete_words(first);
        return NULL;
    }
    regular = (width - len) / (cnt - 1);
    extra = (width - len) % (cnt - 1);
    pBuf = bufOut;
    for ( cur = first; cur != NULL; cur = cur->next ){
        if ( ! memcpy(pBuf, cur->text, cur->len) ){
            free(bufOut);
            delete_words(first);
            return NULL;
        }
        pBuf += cur->len;
        if ( cur->next ){
            for ( i = 0; i < regular; ++i )
                *pBuf++ = ' ';
            if ( extra ){
                *pBuf++ = ' ';
                --extra;
            }
        }
    }
    *pBuf = '\0';
    delete_words(first);
    return bufOut;
}
 
#define WIDTH 60
#define DELIM " \t\n"
 
int main(void){
    char buf[BUFSIZ], * p;
 
    while ( 1 ){
        printf("> ");
        if ( ! fgets(buf, BUFSIZ, stdin) ){
            perror("fgets");
            exit(EXIT_FAILURE);
        }
        if ( *buf == '\n' )
            break;
        if ( p = justify(buf, DELIM, WIDTH) ){
            printf("%s\n", p);
            free(p);
        }
        else {
            fprintf(stderr, "Memory or other error!\n");
            exit(EXIT_FAILURE);
        }
    }
 
    exit(EXIT_SUCCESS);
}
Функция доводит длину строки до заданной, вставляя пробелы между словами
harkonin
0 / 0 / 0
Регистрация: 20.06.2010
Сообщений: 19
23.06.2010, 18:49  [ТС]     Функция доводит длину строки до заданной, вставляя пробелы между словами #5
Спасибо большое!!!
Sanu0074
58 / 58 / 2
Регистрация: 14.06.2010
Сообщений: 1,189
Записей в блоге: 5
23.06.2010, 21:45     Функция доводит длину строки до заданной, вставляя пробелы между словами #6
Цитата Сообщение от easybudda Посмотреть сообщение
о, как!
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct WRD {
    char * text;
    int len;
    struct WRD * next;
} wrd_t;
 
wrd_t * new_word(const char * s, wrd_t * last){
    wrd_t * w;
    if ( ( w = (wrd_t*)malloc(sizeof(wrd_t)) ) == NULL )
        return NULL;
    if ( ( w->text = strdup(s) ) == NULL ){
        free(w);
        return NULL;
    }
    w->len = strlen(w->text);
    w->next = NULL;
    if ( last )
        last->next = w;
    return w;
}
 
int words_len(const wrd_t * w){
    int len = 0;
    while ( w ){
        len += w->len;
        w = w->next;
    }
    return len;
}
 
void delete_words(wrd_t * w){
    wrd_t * t;
    while ( w ){
        t = w->next;
        free(w->text);
        free(w);
        w = t;
    }
}
 
char * justify(const char * s, const char * delim, int width){
    char * bufIn, * bufOut, * pBuf, * pWrd;
    int regular, extra, len, cnt, i;
    wrd_t * first, * last, * cur;
 
    if ( ( bufIn = strdup(s) ) == NULL )
        return NULL;
    cnt = 0;
    first = last = NULL;
    for ( pWrd = strtok(bufIn, delim); pWrd; pWrd = strtok(NULL, delim) ){
        if ( ( last = new_word(pWrd, last) ) == NULL ){
            if ( first )
                delete_words(first);
            return NULL;
        }
        if ( ! first )
            first = last;
        ++cnt;
    }
    free(bufIn);
 
    if ( ! first )
        return NULL;
    if ( cnt == 1 ){
        bufOut = strdup(first->text);
        delete_words(first);
        return bufOut;
    }
 
    len = words_len(first);
    if ( len + cnt - 1 > width ){
        bufOut = strdup("Too long!");
        delete_words(first);
        return bufOut;
    }
 
    if ( ( bufOut = (char*)malloc(width + 1) ) == NULL ){
        delete_words(first);
        return NULL;
    }
    regular = (width - len) / (cnt - 1);
    extra = (width - len) % (cnt - 1);
    pBuf = bufOut;
    for ( cur = first; cur != NULL; cur = cur->next ){
        if ( ! memcpy(pBuf, cur->text, cur->len) ){
            free(bufOut);
            delete_words(first);
            return NULL;
        }
        pBuf += cur->len;
        if ( cur->next ){
            for ( i = 0; i < regular; ++i )
                *pBuf++ = ' ';
            if ( extra ){
                *pBuf++ = ' ';
                --extra;
            }
        }
    }
    *pBuf = '\0';
    delete_words(first);
    return bufOut;
}
 
#define WIDTH 60
#define DELIM " \t\n"
 
int main(void){
    char buf[BUFSIZ], * p;
 
    while ( 1 ){
        printf("> ");
        if ( ! fgets(buf, BUFSIZ, stdin) ){
            perror("fgets");
            exit(EXIT_FAILURE);
        }
        if ( *buf == '\n' )
            break;
        if ( p = justify(buf, DELIM, WIDTH) ){
            printf("%s\n", p);
            free(p);
        }
        else {
            fprintf(stderr, "Memory or other error!\n");
            exit(EXIT_FAILURE);
        }
    }
 
    exit(EXIT_SUCCESS);
}
Вложение 34709
круто, а для чего используется структура?
можеш немножко прокоментить код меня оч заинтересовало))

p.s.
такую задачу можно было решить намного простым методом..., просто когда студент 1го курса который только выучил сортировку массивов и функции, приносит такой сложной структуры код - его начинают грузить и он ничо неможет обьяснит и в итоге 2бала...ну эт фигня, пусть учат!!!
easybudda
Эксперт С++
9458 / 5471 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
23.06.2010, 23:28     Функция доводит длину строки до заданной, вставляя пробелы между словами #7
Цитата Сообщение от Sanu0074 Посмотреть сообщение
а для чего используется структура?
Чтобы список слов составлять. Именно структура для того, чтобы хранить длинну слова и по 10 раз strlen() не вызывать - так нагляднее. Логика самой программы по-моему не дюже сложная - поделить строку на слова. Пропусков между словами при этом должно быть на 1 меньше, чем слов. Дальше вычисляется разница между шириной поля и суммарной длинной слов. Базовое количество пробелов между словами - эта разница, поделенная на число пропусков. Остаток от деления сохраняется в переменной extra, и, пока эта переменная не обнулится, к базовому количеству пробелов добавляется по одному и значение переменной extra уменьшается. Таким образом, если между четырьмя словами нужно распределить 5 пробелов, между первым и вторым, вторым и третьим будет по два пробела, между третьим и четвёртым - один.

Цитата Сообщение от Sanu0074 Посмотреть сообщение
такую задачу можно было решить намного простым методом...,
Ну так что мешает? Решайте! На самом деле "более простой" способ скорее всего обернётся увеличением кода в несколько раз...

Добавлено через 1 минуту
На С++ действительно было бы на много проще, и то за счёт использования STL...
time2die
51 / 51 / 3
Регистрация: 25.05.2010
Сообщений: 182
24.06.2010, 00:01     Функция доводит длину строки до заданной, вставляя пробелы между словами #8
как я вижу эту задачу сейчас, в ближайщее время выкину код
1) считываем строку
2) считаем кол-во пробелов(у нас идеальный мир, где между словами только один пробел)
3) считает кол-во символов, которые нужно вставить
4) делим на кол-во у нас пробелов( остаток от деления впихиваем в последний пробел)
5) выводим

для выполнения лабораторной работы должно хватить

З.Ы.
KISS
Prividenie
74 / 74 / 6
Регистрация: 05.10.2008
Сообщений: 233
24.06.2010, 02:35     Функция доводит длину строки до заданной, вставляя пробелы между словами #9
Цитата Сообщение от easybudda Посмотреть сообщение
На С++ действительно было бы на много проще
я так понимаю нужна была на Си
Цитата Сообщение от harkonin Посмотреть сообщение
Помогите с прогой на С
easybudda
Эксперт С++
9458 / 5471 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
24.06.2010, 02:58     Функция доводит длину строки до заданной, вставляя пробелы между словами #10
Цитата Сообщение от Prividenie Посмотреть сообщение
я так понимаю нужна была на Си
Ну да... Так я на С и написал, не?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.06.2010, 03:03     Функция доводит длину строки до заданной, вставляя пробелы между словами
Еще ссылки по теме:
C++ Исключить лишние пробелы между словами (комментарии)
Строка: Удалить лишние пробелы между словами C++
Выделить в тексте лишние пробелы между словами C++
C++ Напечатать текст, выпустив повторяющиеся пробелы между словами

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

Или воспользуйтесь поиском по форуму:
Prividenie
74 / 74 / 6
Регистрация: 05.10.2008
Сообщений: 233
24.06.2010, 03:03     Функция доводит длину строки до заданной, вставляя пробелы между словами #11
Цитата Сообщение от easybudda Посмотреть сообщение
не?
ниче против не имею... хочу посмотреть реализацию: time2die на си
(самому интересно, кодил ф-ю по его примеру) т.е. принимаем 2 параметра - строка, кол. символов, отдаем туже строку с пробелами, длиной
Yandex
Объявления
24.06.2010, 03:03     Функция доводит длину строки до заданной, вставляя пробелы между словами
Ответ Создать тему
Опции темы

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