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

Линейный список. выравнивание текста. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 20, средняя оценка - 4.70
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 09:29     Линейный список. выравнивание текста. #1
Доброго времени суток. Задача- написать программу реализующую выравнивание текста по центру. ширина строки, имя входного и выходного файлов задаются пользователем с командной строки. Слова, которые превышают по длине заданную ширину строки, должны переносится на следующую строку. абзацы отделяются пустрй строкой. вроде все.

Так вот вопрос, как мне это реализовать? я не могу придумать алгоритм, что за чем делать. Прошу помощи

Добавлено через 13 минут
И какой список лучше использовать: односвязный или двусвязный
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.01.2011, 09:29     Линейный список. выравнивание текста.
Посмотрите здесь:

C++ Линейный список.
C++ Си:Линейный список
C++ Линейный список
C++ Выравнивание текста
C++ [C++] Линейный список
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 09:31     Линейный список. выравнивание текста. #2
Эээ... А это два разных вопроса или один? Потому как связные списки и выравнивание текста у вас ну никак между собой не вяжутся, даже в вопросе, не то что в логике...
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 09:34  [ТС]     Линейный список. выравнивание текста. #3
Цитата Сообщение от silent_1991 Посмотреть сообщение
Эээ... А это два разных вопроса или один? Потому как связные списки и выравнивание текста у вас ну никак между собой не вяжутся, даже в вопросе, не то что в логике...
мой косяк. в задание ещё нужно добавить. "Перемещение слов производится целиком. Для хранения в памяти строк файла использовать линейный список." Вотъ
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 09:35     Линейный список. выравнивание текста. #4
Я бы юзал двусвязный, хотя может вполне хватить и односвязного.
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 09:37  [ТС]     Линейный список. выравнивание текста. #5
Цитата Сообщение от silent_1991 Посмотреть сообщение
Я бы юзал двусвязный, хотя может вполне хватить и односвязного.
а что нибудь по алгоритму сказать можете? я пытался что-то писать, но у меня ничего не получилось=(
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 09:41     Линейный список. выравнивание текста. #6
Ну а что, в принципе ничего сложного. Первым делом, считаем длину одной строки (не всего введённого текста, а одной его строки, до знака переноса строки). Если она короче ширины строки - просто добавляем перед первым и после последнего слова одинаковое число пробелов, пока длина получаемой строки не станет равна ширине строки. Если же длина этой строки больше ширины строки, идём назад по словам, пока не встретим слово, на котором длина от начала строки до конца этого слова не станет меньше ширины, разбиваем строку на две, одна из которых оканчивается найденным словом, а вторая начинается следующим после него, и к этим двум строкам применяем уже описанный алгоритм выравнивания по центру.
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 09:47  [ТС]     Линейный список. выравнивание текста. #7
допустим длина строки больше ширины. строка разделена на две. одна записана, вторая записана. куда мне писать строку, которую я считываю из файла следующей? на новую строку? + мне нужно делать частичный перенос слов=(
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 10:07     Линейный список. выравнивание текста. #8
Гамбит, а вы считывайте весь файл целиком. У вас будет список, скажем так, лексем, где лексема - это слово или конец строки. Тогда текст
Код
Пример выравнивания текста по центру.
будет в виде списка оформлен так
Код
[Пример]->[выравнивания]->[текста]->[по]->[центру.]->[\0]
Вот у вас и будет, например, куча строк, а в списке они будут выглядеть просто как набор элементов, каждый из которых представляет либо слово, либо конец строки. И служебные элементы, например, "абзац", легко в такой список вставлять.

Добавлено через 2 минуты
Ну или если очень хочется, можно и построчно читать. Тогда да, следующую строку, разумеется, писать в файл на новую строку.
Про частичный перенос слов (если имеется ввиду по слогам) в задании не увидел, только про полный перенос.
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 14:09  [ТС]     Линейный список. выравнивание текста. #9
Цитата Сообщение от silent_1991 Посмотреть сообщение
Гамбит, а вы считывайте весь файл целиком. У вас будет список, скажем так, лексем, где лексема - это слово или конец строки. Тогда текст
Код
Пример выравнивания текста по центру.
будет в виде списка оформлен так
Код
[Пример]->[выравнивания]->[текста]->[по]->[центру.]->[\0]
Вот у вас и будет, например, куча строк, а в списке они будут выглядеть просто как набор элементов, каждый из которых представляет либо слово, либо конец строки. И служебные элементы, например, "абзац", легко в такой список вставлять.

Добавлено через 2 минуты
Ну или если очень хочется, можно и построчно читать. Тогда да, следующую строку, разумеется, писать в файл на новую строку.
Про частичный перенос слов (если имеется ввиду по слогам) в задании не увидел, только про полный перенос.
спасибо=) попытаюсь=)

Добавлено через 2 часа 54 минуты
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
#include <stdio.h>
#include <string.h>
#include <alloc.h>
#include<conio.h>
#define n 15
typedef struct list {
char word[80];
struct list *next;
} LIST;
int i,a[100];
 
LIST * read_list(LIST *lst)
{
    LIST *p;
    FILE *f;
    int k;
    f=fopen("f:\\1\\bc\\bin\\1.txt","r");
    if (!feof(f))
    {
        i=1;
        a[1]=0;
        lst=(LIST*)malloc(sizeof(LIST));
        p=lst;
        while(1)
        {
            fscanf(f,"%s",&p->word);
            if(p->word=="\n");{
            i++;a[i]=0;}
            a[i]=a[i]+strlen(p->word);
            if (!feof(f))
            {
                p->next=(LIST*)malloc(sizeof(LIST));
                p=p->next;
            }
            else break;
 
        }
        p->next=NULL;
    }
    else printf("File pustoi\n");
    fclose(f);
    return lst;
}
 
 
 
void main()
{
clrscr();
LIST *lst;
int k;
read_list(lst);
printf("%d\n",i);
for(k=1;k<=i;k++)
printf("%d\n",a[k]);
}
не хочет адекватно считывать кол-во строк. почему?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 14:14     Линейный список. выравнивание текста. #10
В 28 строку после if уберите точку с запятой.
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 14:20  [ТС]     Линейный список. выравнивание текста. #11
Цитата Сообщение от silent_1991 Посмотреть сообщение
В 28 строку после if уберите точку с запятой.
который раз попадаюсь....но все равно не правильно. он не видит следующие строки. выдает кол-во строк 1 и общее кол-во символов.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 14:23     Линейный список. выравнивание текста. #12
В 26 строку уберите & - имя массива является указателем на его начало.
К тому же, перевод строки будет склеен с последним слово в этой строке, т.е. так
Код
[последнее_слово.\n]
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 14:46  [ТС]     Линейный список. выравнивание текста. #13
Цитата Сообщение от silent_1991 Посмотреть сообщение
В 26 строку уберите & - имя массива является указателем на его начало.
К тому же, перевод строки будет склеен с последним слово в этой строке, т.е. так
Код
[последнее_слово.\n]
Про & я знаю, это не критично.

Код
fscanf(f,"%s",p->word);
k=strlen(p->word);
if(p->word[k-1]=="\n")
я пытался так сделать, но ругается на иф, пишет что не может превратить char в char *
ну и то что начение параметра k не используется=(

Добавлено через 16 минут
и ещё не правильно считается длина строки=( текст из 2 строк с кол-вом символов 149. он показывает 1 строку в которой 131 символ=( (хотя он же наверно пробелы игнорирует)
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 14:46     Линейный список. выравнивание текста. #14
Гамбит, вы символ со строкой сравниваете. Пишите '\n', а не "\n"
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 14:55  [ТС]     Линейный список. выравнивание текста. #15
Цитата Сообщение от silent_1991 Посмотреть сообщение
Гамбит, вы символ со строкой сравниваете. Пишите '\n', а не "\n"
это я понял уже=)
if(p->word[k-1]=='\n') при условии, что к длина слова. все равно 1 строку находит=(
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 16:19     Линейный список. выравнивание текста. #16
Балин, что-то быдлокодерски вышло. Но работает. Это только чтение и распихивание по списку слов.

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
145
146
147
148
149
150
151
152
153
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct Node Node;
 
typedef struct Node
{
    char word[80];
    char type;
    int len;
    Node *next;
} Node;
 
typedef struct
{
    Node *first;
    Node *last;
} Words;
 
void scan_words(Words *words, char *filename)
{
    Node *new_elem;
    Node *paragraph;
    Node *end;
    char buffer[1024];
    char word[80];
    char c;
    int len;
    int i, j, k;
 
    FILE *fin;
 
    if ((fin = fopen(filename, "r")) == NULL)
    {
        printf("Error opening file!\n");
 
        exit(-1);
    }
 
    while (!feof(fin))
    {
        i = 0;
 
        while ((c = fgetc(fin)) != '\n' && !feof(fin))
            buffer[i++] = c;
 
        buffer[i] = '\0';
 
        i = 0;
 
        while (buffer[i] != '\0')
        {
            j = i;
 
            while (buffer[j] != ' ' && buffer[j] != '\0')
                ++j;
 
            for (k = i; k < j; ++k)
                word[k - i] = buffer[k];
 
            word[k - i] = '\0';
 
            len = strlen(word);
 
            new_elem = (Node *)malloc(sizeof(Node));
            new_elem->next = NULL;
 
            if (words->first == NULL)
            {
                words->first = new_elem;
                words->last = new_elem;
            }
            else
            {
                words->last->next = new_elem;
                words->last = new_elem;
            }
 
            strcpy(new_elem->word, word);
            new_elem->len = len;
            new_elem->type = 'w';
 
            i = j + 1;
 
            if (buffer[j] == '\0')
                break;
        }
 
        paragraph = (Node *)malloc(sizeof(Node));
        strcpy(paragraph->word, "\n\n");
        paragraph->type = 'p';
 
        words->last->next = paragraph;
        words->last = paragraph;
    }
 
    end = (Node *)malloc(sizeof(Node *));
    end->type = 'e';
 
    words->last->next = end;
    words->last = end;
 
    fclose(fin);
}
 
void print_words(Words *words)
{
    Node *first = words->first;
    Node *next_elem;
    Node *prev_element = words->first;
 
    while (first->type != 'e')
    {
        printf("%s", first->word);
 
        next_elem = first->next;
 
        if (next_elem->type != 'p' && prev_element->type != 'p')
            printf(" ");
 
        first = first->next;
        prev_element = first;
    }
}
 
void delete_words(Words *words)
{
    Node *first = words->first;
    Node *temp;
 
    while (first != NULL)
    {
        temp = first;
        first = first->next;
 
        free(temp);
    }
}
 
int main()
{
    Words words;
 
    words.first = NULL;
    words.last = NULL;
 
    scan_words(&words, "1.txt");
    print_words(&words);
    delete_words(&words);
 
    return 0;
}
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 16:53  [ТС]     Линейный список. выравнивание текста. #17
о мой моцк....сама функция считывания и распихивания у меня работает. у меня не работает подсчет строк и длин строк
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 17:02     Линейный список. выравнивание текста. #18
Гамбит, потому что у вас это самое "считывание и распихивание" неверно реализовано. У вас всё интерпретируется как одна строка, поскольку в файле нету разделения на строки. Поэтому приходится считывать посимвольно. Чем и занимается изрядная часть моей функции. Остальная часть - по сути то же, что и у вас. В мой код добавить подсчёт строк труда не составит.
Гамбит
13 / 13 / 1
Регистрация: 19.10.2009
Сообщений: 93
08.01.2011, 17:54  [ТС]     Линейный список. выравнивание текста. #19
слишком много кода=( мне это в жизн не объяснить преподу
тоесть нужно посимвольно считывать? просто в задании написано, что Перемещение строк производится целиком...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2011, 18:03     Линейный список. выравнивание текста.
Еще ссылки по теме:

Задали односвязный линейный список с целыми числами. Создать новый список, который содержит элементы заданного списка в обратном порядке C++
Линейный список C++

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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
08.01.2011, 18:03     Линейный список. выравнивание текста. #20
Гамбит, ну и что? Перемещение - целиком. А обрабатывать-то их как-то надо. Вот и обрабатываем, как можем, а чтобы удовлетворять заданию, т.е. вообще разбить набор входных символов на строки - приходится читать посимвольно.
Yandex
Объявления
08.01.2011, 18:03     Линейный список. выравнивание текста.
Ответ Создать тему
Опции темы

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