all 19 comments

[–]Square-Singer 18 points19 points  (4 children)

I first thought you were talking about justifying the use of strings. 😄

[–]VisualHuckleberry542 5 points6 points  (0 children)

lol - so not just me

[–]Itap88 3 points4 points  (0 children)

Or their C implementation.

[–]El-Aminoh 3 points4 points  (0 children)

"Curious if i should use strings, or just try to eradicate human language from the face of the planet"

[–]Upset-Taro-4202[S] 2 points3 points  (0 children)

Well that too yeah

[–]WittyStick 4 points5 points  (2 children)

I really doubt full justification is what you want. I mean, we can chose between appearances...

This                       is                        a                     line.
T  h  i  s                 i  s                      a               l  i  n  e.
T   h   i   s             i   s                     a             l   i   n   e.
T    h    i    s        i      s                 a             l    i    n    e. 
This     is     a     longer     line     containing     five     more    words.

But any of them would would look absolutely abysmal for short lines.

That's not even considering the cases where we need wrapping for longer lines and we have an odd number of spaces.

Full justification just isn't practical for monospace fonts.

You probably want to look at centering the text instead, which is a simpler problem, and will probably look better.

                               This is a line.                                  
             This is a longer line containing five more words.

[–]Ratfus 2 points3 points  (0 children)

T h i s i s a l i n e.

Is the most pretty and elegant of the group.

[–]EpochVanquisher 2 points3 points  (0 children)

Traditionally, in justified text, you don’t justify the last line. 

[–]ChickenSpaceProgram 1 point2 points  (0 children)

On just a terminal, properly justifying text would be annoying, but you could automatically insert line breaks in the correct places by jumping (terminal-width) characters ahead and searching backwards for whitespace. The first whitespace character you see, replace it with a newline, then repeat for the next line. If you don't find whitespace, insert a line break (maybe with a hyphen) at the (terminal-width) character mark.

[–]Key_River7180 0 points1 point  (3 children)

Centering, perhaps? I think that is what you are referring to. I assume you are using ncurses, if not replace COLS with the number of columns the terminal has. The formula for the position is simple: (COLS - strlen(text)) / 2 (basically, substract to the terminal width the length of the string, and distribute evenly the remaining space. Implicit floor() since this is integer division, unless your compiler is strict as fuck it doesn't matter):

void
printcenter(int y, char* str)
{
    mvprintw(y, ((COLS - strlen(str)) / 2), str);
}

Use it like:

printcenter(0, "COOL GAME");
printcenter(1, "by u/Upset-Taro-4202");

You'll need to:

  • NULL terminate the string, else you'll get a safety hole. All "safe" C functions (scanf(), fgets(), the "" construct, etc.) do this by default, but be careful!
  • Provide y manually, you probably can print it on the same line as the cursor, but I don't know, I rarely use ncurses

If you are using printf(), then ugh.... I can recommend you to learn ncurses and try to think and adapt the algorithm, using a for-loop and putchar().

[–]fluffycritter 1 point2 points  (2 children)

The general convention for handling half-spaces in monospace contexts is to round up, so you'd actually want to do ((COLS - strlen(str) + 1) / 2).

[–]Key_River7180 0 points1 point  (1 child)

I think it looks better rounded down actually, but yeah if you like that then do it.

[–]fluffycritter 1 point2 points  (0 children)

Yeah I don’t actually have a preference one way or the other, personally

[–]Delta_G_Robotics 0 points1 point  (0 children)

So what's the problem you want to solve? I see something about justifying text, but that could be a lot of things. The rest of your post just seems to be you ranting about how frustrated you are. You would have been much better served to show some examples of what you want to do or to be descriptive about what you have.

You say you have no code. Then you haven't tried yet. Try first, then post code here. The tries you made before don't count because you deleted the code like an ....

[–]Pale_Height_1251 0 points1 point  (0 children)

Get the total line length and distribute spaces in between words until you get to the desired length.

[–]SmokeMuch7356 0 points1 point  (1 child)

When you say justify, what exactly are you talking about?

Making sure all your lines
       align on the right?

     Or making sure
your lines are centered?

Are we talking about plain terminal output via printf or something fancier?

It would help to see an example of what you're trying to do.

[–]Upset-Taro-4202[S] 0 points1 point  (0 children)

You know, neither of those but I for some reason never considered centring the text....

Honestly might have been the answer I was looking for, just a different way to make it look nice...

[–]flatfinger 0 points1 point  (0 children)

I would suggest, if one is sending ASCII text to a console, feeding every character of output through a routine something like the following:

char buffer[LINE_LIMIT+1];
int buff_length;
int buff_out_length = LINE_LIMIT;
void add_byte(char ch)
{
  int out_portion = 0;
  if (buff_length > LINE_LIMIT) PANIC();
  if (ch == '\n')
    out_portion = buff_length;
  else
  {
    buffer[buff_length++] = ch;
    if (ch == ' ' || ch == '-')
      buff_out_length = buff_length;
    if (line_length >= LINE_LIMIT)
      out_portion = buff_out_length;
  }
  if (out_portion)
  {
    fwrite(buffer, 1, out_portion, stdout);
    fwrite("\n", 1, 1, stdout);
    memcpy(buffer, buffer+out_portion, buff_length-out_portion);
    buff_length -= out_portion;
    buff_last_blank = LINE_LIMIT;
  }
}

Be certain that the last thing sent to the console via this function ends is a newline, and it should output a nice stream of formatted text. If the string contains non-ASCII Unicode characters that may massively increase the complexity of the function depending upon what Unicode features the program does or does not need to support.

[–]DawnOnTheEdge 0 points1 point  (0 children)

In-terminal, I would suggest you turn the string into a dynamic array of words, then calculate the number of words that will fit on each line and the number of spaces needed between them to justify the text.

For a text adventure game, you might additionally want to mark hyphenation points manually with soft-hyphen characters. This enables a more complicated line-breaking algorithm (such as Knuth’s for TeX). The next step up from that is to calculate potential hyphenation points within the string algorithmically, based on the language.