Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
12 / 12 / 16
Регистрация: 18.05.2017
Сообщений: 45
1

Файлы: выравнивание всех строк до длины максимальной строки (добавление пробелов между словами)

18.10.2017, 23:22. Показов 1858. Ответов 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
135
136
137
138
#include <stdio.h>
#include <string.h>
 
int max (FILE *);
int quant_word(char *);
 
int main ()
{
    FILE *f;
    FILE *f_out;
    char buf[256];
    char tmp[256];
    char *word;
    char *space_end;
    int max_str;
    int leng_str;
    int quant_space; 
    int quant_words;
    f = fopen ("input.txt", "r");
    if (f == NULL)
    {
        printf("File couldn't been opened");
        return 0;
    }
    else
    {
        f_out = fopen ("output.txt","w");
 
        max_str = max (f);       // Функция возвращает длину макс. строки
        if (max_str == -1)
        {
            printf("Read error");
            fclose(f);
            fclose(f_out);
            remove ("output.txt");
            return 0;
        }
 
        rewind(f);
        
        while (fgets(buf,256,f))
        {
            strcpy(tmp,buf);
 
            leng_str = strlen(buf);
            if (buf[leng_str - 1] == '\n')
                leng_str--;
 
            quant_words = quant_word(buf);  // Функция возвращает кол-во слов в строке
 
            if (quant_words == 1)
            {
                quant_space = max_str - leng_str + strspn(tmp, " ");
                space_end = tmp + strspn(tmp, " ");
                if (space_end = strchr(space_end, ' '))
                    quant_space += tmp + leng_str - space_end;
                memset(buf,' ', quant_space);
                word = strtok(tmp, " ");
                strcpy(buf + quant_space, word);
                word = strtok(NULL, " ");
                if (word)
                    strcat(buf, word);  
                if (fputs(buf,f_out) == EOF)
                {
                    printf ("Write error");
                    fclose (f);
                    fclose (f_out);
                    remove ("output.txt");
                    return 0;
                }
            }
            else if (quant_words > 1)   // Вот здесь проблема, видимо, из-за формулы
            {                           // для определения кол-ва вставляемых пробелов
                quant_space = (max_str - leng_str) / (quant_words - 1);
                memset(buf,'\0',1);
                word = strtok (tmp," ");
                while (word != NULL)
                {
                    strcpy(buf + strlen(buf), word);
                    if (--quant_words)
                    {
                        for (int i = 0; i <= quant_space; i++)
                            strcat(buf," ");
                    }
 
                    word = strtok(NULL," ");
                }
                if ((max_str - leng_str) % (quant_space))
                        strcat(buf, " ");
                fputs(buf,f_out);
            }
            else if (fputs(tmp, f_out) == EOF)
            {
                printf ("Write error");
                fclose (f);
                fclose (f_out);
                remove ("output.txt");
                return 0;
            }
        }
        if (ferror(f) == 1)
            printf("Read error");
        fclose(f);
        fclose(f_out);
    }
}
 
 
int max (FILE *in)
{
    char buf[256];
    int max_str = 0;
    int leng_str;
    while (fgets(buf,256,in))
    {
        leng_str = strlen(buf);
        if (buf[leng_str - 1] == '\n')
            leng_str--;
        if (leng_str > max_str)
            max_str = leng_str;
    }
    if (ferror(in) == 1)
        return -1;
    return max_str;
}
 
int quant_word(char *line)
{
    int quant_words = 0;
    char *word;
    word = strtok(line," \n");
    while (word != NULL)
    {
        quant_words++;
        word = strtok(NULL," \n");
    }
    return quant_words;
}
Прощу помощи. Формула для определения кол-ва вставляемых пробелов не всегда правильно работает. Я примерно понимаю почему, но не точно не знаю, как это исправить.

P.S. Еще нужно сделать, чтобы работало правильно с табуляцией (табуляция - 2 пробела)
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.10.2017, 23:22
Ответы с готовыми решениями:

Определить количество слов в строке между словами максимальной и минимальной длины
Ввести с клавиатуры строку. Определить количество слов в строке между словами максимальной и...

Удаление из строки всех слов с максимальной длинной (и всех пробелов после них)
С клавиатуры вводится строка символов, необходимо найти самое длинное слово (несколько слов) и...

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

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

4
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
19.10.2017, 10:53 2
Лучший ответ Сообщение было отмечено DonSangre как решение

Решение

Когда-то делал похожее задание на плюсах.
В нём требовалось сделать выравнивание текста по ширине, установив длину колонки.
Надеюсь, поможет.
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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std; // используем пространство имён std по умолчанию
 
int main()
{
    string fileIn, fileOut; // имена файлов для ввода и вывода
    int N; // количество символов в строке
 
    cout << "input text file name: ";
    cin >> fileIn;
    ifstream ifs(fileIn.c_str()); // создаём поток на считывание с файла
    if (!ifs)
    {
        cerr << "file not found\n";
        return 1;
    }
    cout << "output text file name: ";
    cin >> fileOut;
    do
    {
        cout << "text width to format (> 10): ";
        cin >> N;
        if (N <= 10)
            cout << "too small length\n";
    } while (N <= 10);
 
    cout << "start formatting...";
    ofstream ofs(fileOut.c_str()); // создаём поток на запись в файл
 
    vector<string> words; // будет содержать все слова из текста
    // пока удалось считать слово из файла - добавляем его в words
    for (string word; ifs >> word; words.push_back(word))
    {}
 
    int indexOfLineBegin = 0; // индекс указывает на слово, с которого будет начинаться новая строка
    int curLength = 0; // текущая длина слов в сформированной строке
    for (unsigned int i = 0; i < words.size(); i++) // проходимся по нашему набору слов
    {
        // необходимое место под новое слово + пробел
        const int lengthForNewWord = words[i].length() + 1;
        // если мы можем добавить слово в строку (последний пробел не нужен)
        if (curLength + lengthForNewWord - 1 < N)
            curLength += lengthForNewWord;
        else // иначе
        {
            // узнаём сколько слов уже есть в строке
            const int wordsInLine = i - indexOfLineBegin;
            // если имеем только одно слово - не нужно ничего рассчитывать, просто его выводим
            if (wordsInLine != 1)
            {
                // количество недостающих пробелов
                const int neededExtraWhitespaces = N - curLength;
                // общее количество пробелов в строке
                const int whitespacesTotal = wordsInLine + neededExtraWhitespaces;
                // узнаём количество шагов (разделений между словами)
                const int steps = wordsInLine - 1;
                // узнаём количество пробелов в каждом шаге
                const int whitespacesInStep = whitespacesTotal / steps;
 
                // выводим слова и пробелы до предпоследнего слова
                for (unsigned int j = indexOfLineBegin; j < i - 1; j++)
                {
                    ofs << words[j]; // выводим очередное слово
                    for (int n = 0; n < whitespacesInStep; n++) // выводим пробелы
                        ofs << ' ';
                }
                // узнаём количество пробелов, которые нужно дополнительно добавить перед последним словом
                const int alreadyAddedWhitespaces = whitespacesInStep * steps;
                const int extraWhitespacesInLastStep = whitespacesTotal - alreadyAddedWhitespaces;
                for (int n = 0; n < extraWhitespacesInLastStep; n++)
                    ofs << ' ';
            }
            ofs << words[i - 1] << endl; // выводим последнее слово и перенос строки
 
            // считаем, что считанное слово положит начало новой строке
            curLength = lengthForNewWord;
            indexOfLineBegin = i;
        }
    }
    // если осталось что-то, что не вывели
    for (unsigned int i = indexOfLineBegin; i < words.size(); i++)
        ofs << words[i] << ' '; // выводим оставшиеся слова через пробел
 
    cout << "done";
}
0
1265 / 1023 / 469
Регистрация: 25.12.2016
Сообщений: 3,331
19.10.2017, 12:44 3
Вот ещё похожая тема: Выровнять строки в файле по правой и левой границе, вставляя между словами пробелы
0
12 / 12 / 16
Регистрация: 18.05.2017
Сообщений: 45
19.10.2017, 21:54  [ТС] 4
MrGluck, спасибо, действительно похоже, я правильно понял, что у вас вставляются пробелы до предпоследнего слова, затем еще раз смотрим нужно ли добавить еще немного пробелов к исходному числу вставляемых пробелов, чтобы точно выравнять, после этого выравниваем и уже доходим до последнего?
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
20.10.2017, 00:07 5
DonSangre, да. перед последним словом добавляется остаток пробелов. При этом он меньше, чем количество пробелов между другими словами.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.10.2017, 00:07

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

Разработать функцию, которая сравнивает две строки, игнорируя количество пробелов между словами.
Пишу в Microsoft Visual Studio -&gt;Win32 Console application -&gt;C++. Помогите пожалуйста Разработать...

Разработать функцию, которая сравнивает две строки, игнорируя количество пробелов между словами
Имеется такое задание: Разработать функцию, которая сравнивает две строки, игнорируя количество...

Ввод строки, определение ее длины, и удаление в ней всех пробелов
Введите строку, определите ее длину, и удалите в ней все пробелы (предложите вариант без...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

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