строка — Базовое текстовое обоснование C ++

Я пытаюсь закодировать программу, которая берет строку ввода из файла и делает ее ровно 80 символов (допустим, строка ввода всегда меньше 80), а затем печатает строку. Это делается путем добавления до двух пробелов после следующей пунктуации:.,!;? Если строка содержит менее 41 символа, она печатается без изменений.

Если в строке по-прежнему не 80 символов, по всей строке могут быть добавлены случайные пробелы, однородность для этого не имеет значения.

Входной файл:
Является ли Lorem Ipsum просто фиктивным текстом для полиграфии и верстки? Lorem
Ipsum был стандартным фиктивным текстом в отрасли с 1500-х годов, когда
неизвестный принтер взял камбуз типа и скремблировал его, чтобы сделать образец типа
книга. Он пережил не только пять веков, но и скачок в электронику
набор текста, оставаясь практически без изменений. Он был популяризирован в 1960-х годах
с выпуском листов Letraset, содержащих отрывки Lorem Ipsum, и многое другое
недавно с настольным издательским программным обеспечением, таким как Aldus PageMaker, включая
версии Lorem Ipsum.

Выходной файл должен выглядеть так:

Это. Обратите внимание, что каждая строка одинакова

введите описание изображения здесь

Вот мой код:

const int maxLine = 80;

ifstream fin("unjustified.txt");
ofstream fout("justified.txt");

void randomSpace(string &input);
void spaceAdder(string &input);

int main() {

string inputLine;

while (getline(fin, inputLine)) {

if (inputLine.size() > 40)
{
spaceAdder(inputLine);
}

else {
fout << inputLine << endl;

}
}

system("pause");
fin.close();
fout.close();
return 0;
}

void spaceAdder(string &input) {int perPos = input.find('.');
while (perPos != string::npos && input.size() < maxLine) {
input.insert(perPos + 1, " ");
perPos = input.find('.', perPos + 1);
}int commaPos = input.find(',');
while (commaPos != string::npos && input.size() < maxLine) {
input.insert(commaPos + 1, " ");
commaPos = input.find(',', commaPos + 1);
}int questPos = input.find('?');
while (questPos != string::npos && input.size() < maxLine) {
input.insert(questPos + 1, " ");
questPos = input.find('?', questPos + 1);
}int semiPos = input.find(';');
while (semiPos != string::npos && input.size() < maxLine) {
input.insert(semiPos + 1, " ");
semiPos = input.find(';', semiPos + 1);
}int exclamPos = input.find('!');
while (exclamPos != string::npos && input.size() < maxLine) {
input.insert(exclamPos + 1, " ");
exclamPos = input.find('!', exclamPos + 1);
}if (input.size() < maxLine) {
randomSpace(input);}
else
fout << input << endl;}void randomSpace(string &input) {

srand(time(0));

while (input.size() < maxLine) {int spacePos = input.find(" ");
bool i = (rand() % 2 == 1) ? true : false;

if (i = true && spacePos != string::npos)
{
input.insert(spacePos, " ");
spacePos = input.find(" ", spacePos + 1);

}

}

fout << input << endl;
}

Однако вывод, который создает мой код:

Это. Обратите внимание, что строки 2 и 4 не выровнены с остальным текстом

введите описание изображения здесь

Я не могу на всю жизнь понять, что не так с моим кодом. Пожалуйста, укажите мне в правильном направлении! Спасибо

1

Решение

Простой код C ++ может быть:

std::ifstream input_file_stream( "file" );

unsigned counter = 0;
while( ++counter <= 80 && std::char_traits< char >::not_eof( input_file_stream.peek() ) ){
std::cout << char ( input_file_stream.get() );
if( counter == 80 ){
std::cout << '\n';
counter = 0;
}
}

длина вывода каждой строки составляет 80 символов:

введите описание изображения здесь


НОТА

Вместо того, чтобы использовать std::cout Вы можете записать его в выходной файл
Также здесь отсутствуют некоторые слова, такие как the в конце строки 2 и начале строки 3.
Поэтому другое решение может быть примерно таким:

вход:

Is Lorem Ipsum just dummy text of the printing and typesetting industry? Lorem
Ipsum has been the industry's standard dummy text ever since the 1500s, when
an unknown printer took a galley of type and scrambled it to make a type specimen
book. It has survived not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in the 1960s
with the release of Letraset sheets containing Lorem Ipsum passages, and more
recently with desktop publishing software like Aldus PageMaker including
versions of Lorem Ipsum.

Код C ++:

std::ifstream input_file_stream( "file" );

unsigned max_size = 0;
for( std::string line; std::getline( input_file_stream, line );  ){
// find the longest line
if ( max_size < line.size() ) max_size = line.size();
}

input_file_stream.clear();
input_file_stream.seekg( 0 , std::ios_base::beg );  // rewind

for( std::string line; std::getline( input_file_stream, line );  ){

if( line.size() == max_size ){
std::cout << line << '\n';

} else if (  line.size() > 70 ) {

line.insert( line.rfind( ' ' ),std::string(  max_size - line.size() ,' ' ) );
std::cout << line << '\n';

} else {
std::cout << line << '\n';
}
}

input_file_stream.close();

выход:

Is Lorem Ipsum just dummy text of the printing and typesetting industry?    Lorem
Ipsum has been the industry's standard dummy text ever since the 1500s,      when
an unknown printer took a galley of type and scrambled it to make a type specimen
book. It has survived not only five centuries, but also the leap into  electronic
typesetting, remaining essentially unchanged. It was popularised in the     1960s
with the release of Letraset sheets containing Lorem Ipsum passages, and     more
recently with desktop publishing software like Aldus PageMaker          including
versions of Lorem Ipsum.

как это устроено

Это так просто. Прежде всего вам нужно найти самую длинную строку, которая здесь 81 а затем на основе этой самой длинной строки вы можете обосновать другие строки с помощью line.rfind (значит найди последнюю вещь) и line.insert вставить то, что вы хотите. Вам решать, какой размер должен быть длиной каждой строки. Здесь я использовал от 81 до 70.

Каждая строка обоснована на основе этой строки:

неизвестный принтер взял камбуз типа и скремблировал его, чтобы сделать образец типа

Но здесь результат не красивый, так как все пространство собралось в конце. Для этого вы можете распространять все пространство между другим пространством в else if раздел, как это:

    } else if (  line.size() > 70 ) {

unsigned need_space = max_size - line.size();
unsigned count_space = std::count( line.begin(), line.end(), ' ' );

std::istringstream iss( line );
std::string temp_line;

while( need_space-- && count_space-- ){
std::string temp;
iss >> temp;
temp_line +=  temp + "__";
}
iss.get();  // get rid of a single space in the iss stream
// extracts the rest of the iss stream:
temp_line.append(  std::istreambuf_iterator<char>( iss ), std::istreambuf_iterator<char>() );
std::cout  << temp_line << '\n';

} else {
std::cout << line << '\n';
}

выход:

Is__Lorem__Ipsum__just dummy text of the printing and typesetting industry? Lorem
Ipsum__has__been__the__industry's__standard dummy text ever since the 1500s, when
an unknown printer took a galley of type and scrambled it to make a type specimen
book.__It has survived not only five centuries, but also the leap into electronic
typesetting,__remaining__essentially__unchanged.__It was popularised in the 1960s
with__the__release__of__Letraset sheets containing Lorem Ipsum passages, and more
recently__with__desktop__publishing__software__like__Aldus__PageMaker__including
versions of Lorem Ipsum.

Как вы можете видеть здесь, я использовал __ вместо 2-spaces чтобы показать, что происходит на выходе, так что вы можете изменить его на 2 пробела.
Хотя у кода все еще есть пара проблем, таких как линия до последнего это не исправлено, как другие, но я не хочу усложнять код и думаю, что этого будет достаточно для большинства случаев.

1

Другие решения

Ваш spaceAdder функция только проверяет длину строки

if (input.size() < maxLine) {
randomSpace(input);
}
else
fout << input << endl;

после того, как все знаки препинания были добавлены.

0

Где у вас есть:

while (input.size() < maxLine) {...}

Я считаю, что вы хотели бы иметь:

//changed < to <=
while (input.size() <= maxLine) {...}

То же самое касается:

if (input.size() < maxLine) {
randomSpace(input);
}

Изменить на:

//changed < to <=
if (input.size() <= maxLine) {
randomSpace(input);
}
0

Вот мой взгляд на это. Я предположил, что ваш вводимый текст был на самом деле пунктирными линиями, а не одной длинной строкой, которая на самом деле сильно упростит ситуацию, как показывает ответ k-Five.

Мой входной файл: (Первая строка должна обеспечить правильную работу нескольких знаков препинания в строке)

a.b,c.d,e?f;g?h!i.j;k?l,ma.b,c.d,e?f;g?h!i.j;k?l,m
Lorem Ipsum just dummy text of the printing and typesetting industry? Lorem
Ipsum has been the industry's standard dummy text ever since the 1500s, when an
unknown printer took a galley of type and scrambled it to make a type specimen
book. It has survived not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in the 1960s
with the release of Letraset sheets containing Lorem Ipsum passages, and more
recently with desktop publishing software like Aldus PageMaker including
versions of Lorem Ipsum.

Мой код:

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>

using namespace std;

const int maxLine = 80;

void padAfterPunctuation(string &input)
{
const std::string punct = ".,?;!";

for (char p : punct)
// for(size_t i = 0; i < punct,size(); ++i) if you can't use a range based for loop.
// use punct[i] rather than p in find below as well.
{
size_t pos = 0;
while ((pos = input.find(p, pos)) != string::npos && input.size() < maxLine)
{
input.insert(++pos, " ");
}
}
}

void padRandomAfterSpace(string &input)
{
size_t pos = 0;
while (input.size() < maxLine)
{
pos = input.find(' ', pos);
if (pos < input.size() && pos != string::npos)
{
if (rand() & 1)
{
input.insert(pos, " ");
}
pos = input.find_first_not_of(' ', pos);
}
else
{
pos = 0;
}
}
}

int main()
{
srand(time(0));

ifstream fin("unjustified.txt");
ofstream fout("justified.txt");
string inputLine;

while (getline(fin, inputLine))
{
if (inputLine.size() > 40 && inputLine.size() < maxLine)
{
padAfterPunctuation(inputLine);
if (inputLine.size() < maxLine)
{
padRandomAfterSpace(inputLine);
}
}
fout << inputLine << endl;
}
return 0;
}

Я не тратил слишком много времени на выяснение того, где работает ваш код, но, глядя на него, я подозреваю, что c.z. верно. Вместо того, чтобы добавлять больше кода к чрезмерно длинной и сложной функции, которую я выбрал для упрощения, что позволяет легко проверять длину строки после добавления каждого пробела.

Я также решил сделать ваши файлы локальными переменными в main и иметь одно место, куда записываются данные. Лучше всего, чтобы область видимости была как можно меньше, и чтобы каждая функция несла единственную ответственность, чтобы избежать возможности записи данных более одного раза. Я не закрываю файлы явно, так как они закрываются автоматически, когда они выходят из области видимости.

Пример вывода:

a.  b, c.  d,  e?  f; g? h!  i.  j; k? l, ma. b, c. d, e? f; g? h! i. j; k? l, m
Lorem Ipsum  just dummy  text of  the  printing and typesetting industry?  Lorem
Ipsum has been the industry's standard dummy text ever since the 1500s,  when an
unknown printer took  a galley  of type and scrambled it to make a type specimen
book. It has survived not only five centuries, but also the leap into electronic
typesetting,   remaining essentially unchanged.  It was popularised in the 1960s
with the release  of  Letraset sheets containing Lorem Ipsum passages,  and more
recently   with  desktop  publishing  software like  Aldus  PageMaker  including
versions of Lorem Ipsum.
0
По вопросам рекламы [email protected]