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

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

18.10.2017, 23:22. Просмотров 914. Ответов 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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.10.2017, 23:22
Ответы с готовыми решениями:

Обработать строку на основе удаления лишних пробелов между словами
Требуется разработать программу,которая обеспечивает: 1.возможность ввода...

Удалить каждое четное слово в строке, при этом между словами может стоять не 1, а несколько пробелов
Требуется удалить каждое четное слово в строке, при этом между словами может...

Не отслеживается превышение максимальной длины строки
int get_line(char * s,int lim) { int i=0; while...

Удаление всех пробелов из строки
Помогите справиться с задачей на языке C. Нужно из строки удалить все пробелы...

Удаление всех пробелов из строки
Здравствуйте. Нужно удалить из большой строки все пробелы. // Убираем все...

4
MrGluck
Модератор
Эксперт CЭксперт С++
8108 / 4960 / 1436
Регистрация: 29.11.2010
Сообщений: 13,456
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
likehood
984 / 828 / 396
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
19.10.2017, 12:44 3
Вот ещё похожая тема: Выровнять строки в файле по правой и левой границе, вставляя между словами пробелы
0
DonSangre
12 / 12 / 16
Регистрация: 18.05.2017
Сообщений: 45
19.10.2017, 21:54  [ТС] 4
MrGluck, спасибо, действительно похоже, я правильно понял, что у вас вставляются пробелы до предпоследнего слова, затем еще раз смотрим нужно ли добавить еще немного пробелов к исходному числу вставляемых пробелов, чтобы точно выравнять, после этого выравниваем и уже доходим до последнего?
0
MrGluck
Модератор
Эксперт CЭксперт С++
8108 / 4960 / 1436
Регистрация: 29.11.2010
Сообщений: 13,456
20.10.2017, 00:07 5
DonSangre, да. перед последним словом добавляется остаток пробелов. При этом он меньше, чем количество пробелов между другими словами.
0
20.10.2017, 00:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.10.2017, 00:07

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

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

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


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

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

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