简体   繁体   中英

Is there a way to prevent words from getting 'cut' in C++ output?

I have written this simple program in C++ to print the contents of a.txt file.

void printrules(){
    string rule_path = "myfiles/rulebook.txt";
    ifstream fin;
    fin.open(rule_path.c_str());

    if (fin.fail()){
        cout << "Sorry, there was an error in displaying the rules." <<endl;
    }

    string x;
    while (fin >> x)
        cout << x << " ";

    fin.close();
}

int main(){
    printrules;
}

But I cannot think of a way to stop the words from getting "cut" when they are output to the console. For example:

图片

In the first line, 'h' and 'e' got separated, and the same thing happened for the last words in the second and third lines too.

Is there a way to make sure the words remain whole without making the length of the lines fixed?

There are quite a few ways to do this, but here's one that's fairly simple and easy.

#include <sstream>
#include <string>
#include <iostream>

void wrap(std::string const &input, size_t width, std::ostream &os, size_t indent = 0) {
    std::istringstream in(input);

    os << std::string(indent, ' ');
    size_t current = indent;
    std::string word;

    while (in >> word) {
        if (current + word.size() > width) {
            os << "\n" << std::string(indent, ' ');
            current = indent;
        }
        os << word << ' ';
        current += word.size() + 1;
    }
}

int main() {
    char *in = "There was a time when he would have embraced the change that was coming. In his youth he"
    " sought adventure and the unknown, but that had been years ago. He wished he could go back and learn"
    " to find the excitement that came with change but it was useless. That curiousity had long ago left"
    " him to where he had come to loathe anything that put him out of his comfort zone.";

    wrap(in, 72, std::cout, 0);
    return 0;
}

This implicitly assumes that you want to remove an extra white space that might be present in your input string, so if (for example) you started with your text formatted for 60 columns with a 5-character indent:

     There was a time when he would have embraced the change
     that was coming. In his youth he sought adventure and
     the unknown, but that had been years ago. He wished he
     could go back and learn to find the excitement that
     came with change but it was useless. That curiousity
     had long ago left him to where he had come to loathe
     anything that put him out of his comfort zone.

...but you asked for it to be word-wrapped at 72 columns with no indentation, it would get rid of the white space being used for the previous indentation, so it would come out like this:

There was a time when he would have embraced the change that was coming.
In his youth he sought adventure and the unknown, but that had been
years ago. He wished he could go back and learn to find the excitement
that came with change but it was useless. That curiousity had long ago
left him to where he had come to loathe anything that put him out of his
comfort zone.

Another possibility, especially if you want to word-wrap all the output to a particular stream, would be to use the word-wrapping streambuf I posted in another answer .

I took the accepted answer above and made it so the modified it so the stringstream would be able to detect newlines from the original input text. Here's the code:

void wrap(std::string const &input, int width, std::ostream &os, size_t indent = 0) {std::istringstream in(input);
os << std::string(indent, ' ');
size_t current = indent;
std::string line;
std::string word;
string output = "";

while(getline(in,line))
{
    std::istringstream linein(line);
    while (linein >> word) {
        if (current + word.size() > width) {
            output += "\n" + std::string(indent, ' ');
            current = indent;
        }
        output +=  word + ' ';
        current += word.size() + 1;
    }
    output += "\n" + std::string(indent, ' ');
    current = indent;
}

os << output;

I'm new to using stackoverflow, so I hope the formatting doesn't come out too ugly.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM