基本C ++文本对齐

时间:2017-03-20 02:05:14

标签: c++ string justify

我正在尝试编写一个程序,该程序从文件中获取输入行并使其正好为80个字符(假设输入行总是小于80),然后打印该行。这是通过在以下标点后添加UP到两个空格来完成的:。,!;?如果一行少于41个字符,则打印时不进行修改。

如果该行仍然不是80个字符,则可以在整个行中添加随机空格,均匀性对此无关紧要。

输入文件为: Lorem Ipsum只是印刷和排版行业的虚拟文本吗? LOREM 自16世纪以来,Ipsum一直是业界标准的虚拟文本 未知的打印机拿了一个类型的厨房,并乱扰它制作一个类型标本 书。它不仅存在了五个世纪,而且还延伸到了电子领域 排版,基本保持不变。它在20世纪60年代得到普及 随着包含Lorem Ipsum段落的Letraset板块的发布,以及更多 最近使用像Aldus PageMaker这样的桌面出版软件 Lorem Ipsum的版本。

输出文件应如下所示:

此。注意每一行是如何证明相同的

enter image description here

这是我的代码:

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行如何与文本的其余部分无法对齐

enter image description here

我不能为我的生活弄清楚我的代码有什么问题。请指出我正确的方向!感谢

4 个答案:

答案 0 :(得分: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个字符:

enter image description here

您可以将其写入输出文件中,而不是使用std::cout 此外,在第2行的末尾和第3行的开头,有些单词缺少the 因此,另一种解决方案可能是这样的:

输入

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(意味着找到最后的东西)和{{来证明其他行的合理性。 1}}插入你想要的东西。决定每条线的长度应取决于你。我在81到70之间使用过。

根据这一行证明每一行是合理的:

  

一个未知的打印机拿了一个类型的厨房并乱扰它制作一个类型标本

但是这里的输出并不漂亮,因为所有空间都聚集在最后。为此,您可以在line.insert部分的其他空间之间传播所有空间,如下所示:

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个空格。 虽然代码仍然有一些问题,例如前一行并没有像其他人那样修复,但我不想让代码变得复杂,我认为这对大多数情况来说已经足够了。

答案 1 :(得分:0)

您的spaceAdder函数仅检查字符串的长度

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

在添加了所有标点符号后。

答案 2 :(得分: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);
}

答案 3 :(得分: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.