0

This is technically two things, but they're essentially the same so I combined them into one question.

I want to print long messages without having to control where a line break is in the text. For example, I wrote a long string and printed it with std::cout << str << std::endl;. Pipes | added here for demonstration purposes showing the end of the console line at the current window size, and an @ sign to show where the text stopped printing when not at the end where the pipe is.

$ ./text_test
This sentence is so long that the word 'developer' splits into two, and the deve|
loper has no clue how this placeholder sentence was a good idea at the time.@   |
$

What I want this example text to look like printed is this:

$ ./text_test
This sentence is so long that the word 'developer' splits into two, and the@    |
developer has no clue how this placeholder sentence was a good idea at the time.|
$

There should also be no space after the 'the' at the end of the first line, because with the right sentence, the space spills over onto the next line, as shown by this example, with the code for it beneath the output:

$ ./long_test
You are lost in the forest and you have nothing on you. How did you end up here?|
 Questions can be answered later; looks like trouble is on its way! Prepare for |
battle! @
$
// here ^ notice how there is a space after the ! sign, when there shouldn't be,
// and also notice the improper space before "Questions".
// The second line should have also ended with 'r', not ' ', as I've marked by
// the lack of an @ sign after "for".
// Source code:

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

void lprint (std::string str) {
  std::istringstream ss;
  std::string unit;
  while (ss >> unit) {
    std::cout << unit << " ";
  }
}

int main() {
  std::string str " /* long message */ ";
  std::cout << str << std::endl;
  return 0;
}

I would also like to know (if this is mutually exclusive with what I'm already asking) how to detect the end of a line on-screen, perhaps by the number of columns of text that can be displayed (like 80 etc.). Thank you very much.

  • I'll will be honest with you -- the solution to this is to get your hands dirty and write the code to do this. There is no built-in auto line break functionality for output streams. – PaulMcKenzie Mar 30 '21 at 08:06
  • I assumed as much, but that's the issue, I couldn't get anything to work because I can't detect how many characters is too much for 1 line. Assuming I have a known line length, sure, that's straightforward to program, but I need a universal function. Plus, if I were to make a program needing the width of the window to be at least x characters, I need to be able to confirm that the width is at least x characters. – Patrick O'Brien Mar 30 '21 at 08:17
  • *I couldn't get anything to work because I can't detect how many characters is too much for 1 line.* - -I'll be honest again -- this is the type of assignment they give to college students. It is not as trivial as it looks, which is why they give this assignment in college. You basically have to plan out how to do this, and not jump straight into writing code. Word length, margins, how to determine if a word will "break" at the end and go to the beginning of the next line, etc. There are even videos of explaining various techniques to use. – PaulMcKenzie Mar 30 '21 at 08:25
  • Separate things... determining the available line width is one task and it depends on your environment (windows, linux, ... cmd, powershell, ... can the user re-size the output during execution? ...). Splitting text (with equal spaced letters) for a given line width is another task and should be an environment independent programming task. Since the tasks are separate and the necessary clarifications for the sub-tasks are different, this is not a good combination for a single question. – grek40 Mar 30 '21 at 10:23
  • @grek40 actually I'm inclined to disagree. They may be separate tasks from an implementation standpoint, but they are all directed toward the same purpose in a program, which is displaying text in the console, and the reason why I combined them into the same question is because, if I were to compress everything into one question, is "How can I display text in the console without breaking words at the end of a console line, while compensating for the width of the console window?" but that is, in my opinion, very wordy, and I figured it would be better to elaborate in the description. – Patrick O'Brien Mar 30 '21 at 10:48
  • @PatrickO'Brien maybe I'm wrong :) anyway, since you want an answer, you should include all the system details that are needed to answer the *"available line width"* part of the question. – grek40 Mar 30 '21 at 11:10
  • Actually I think I've found my answer here, https://stackoverflow.com/questions/23369503/get-size-of-terminal-window-rows-columns – Patrick O'Brien Mar 30 '21 at 11:26

1 Answers1

0

You could use a function like

void OutputText(std::string s)
{
    int bufferWidth = GetBufferWidth();
 
    for (unsigned int i = 1; i <= s.length() ; i++)
    {
        char c = s[i-1];
 
        int spaceCount = 0;
 
        // Add whitespace if newline detected.
        if (c == ‘n’)
        {
            int charNumOnLine = ((i) % bufferWidth);
            spaceCount = bufferWidth – charNumOnLine;
            s.insert((i-1), (spaceCount), ‘ ‘);
            i+=(spaceCount);
            continue;
        }
 
        if ((i % bufferWidth) == 0)
        {
            if (c != ‘ ‘)
            {
                for (int j = (i-1); j > -1 ; j–)
                {
                    if (s[j] == ‘ ‘)
                    {
                        s.insert(j, spaceCount, ‘ ‘);
                        break;
                    }
                    else spaceCount++;
                }
            }
        }
    }
 
    // Output string to console
    std::cout << s << std::endl;
 }

Which is further explained on this website.

debruss
  • 149
  • 8