3

I did manage to get to the horizontal line (row) to the center but not vertically. Please help, I am still a noob so if you can explain your code, that would be much appreciated.

Thanks

#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>

int main()
{

    struct winsize w; 
    ioctl(0, TIOCGWINSZ, &w); 

    int columns = w.ws_col; 
    int rows = w.ws_row;


    //printf("Lines :  %d\n", rows);
    //printf("Columns ; %d\n", columns);

    char *string = "Hello World";
    int stringLength = strlen(string) / 2;



    printf("%*s\n", columns / 2 + stringLength, string );
    //getchar();                //Pause program

    return 0;
}
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
chichacail
  • 65
  • 1
  • 2
  • 6
  • 3
    Did you want to use C or C++ language? The C++ language has `iostream` but the C language doesn't. Your answers will depend on the language you choose. – Thomas Matthews Feb 10 '15 at 22:41
  • What operating system are you using? For Linux, I think you can position the cursor using ncurses. Place the cursor on the middle line before your `printf`. – yellowantphil Feb 10 '15 at 22:42

5 Answers5

2

No idea why this was down voted. Seems a perfectly valid question.

You've solved the horizontal. Nice job!

If you are in a UNIX environment (Bash especially) you can query the environment variables $LINES and $COLUMNS to find out what the length and width of the screen is.

David Hoelzer
  • 15,862
  • 4
  • 48
  • 67
  • `$LINES` and `$COLUMNS` aren't exported by default on my system, RHEL, so you can't necessarily read those variables from C. I think I've done something with [TIOCGWINSZ](http://stackoverflow.com/questions/1022957/getting-terminal-width-in-c) before. – yellowantphil Feb 10 '15 at 22:52
1

Last time I used the centering formula it was:

left_column = (width / 2) - (text/2);

So you could brute for this:

const std::string hw = "Hello World!"; 
unsigned int spaces = (columns / 2) - (hw.length() / 2);
for (unsigned int i = 0; i < spaces; ++i)
{
  std::cout << ' ';
}
std::cout << hw << std::endl;

Edit 1:
The above assumes the use of a fixed-pitch font.
For variable pitch font, you will need to sum up all the character widths and spacings. The string length will not suffice.

Edit 2:
Another way to cheat is to use the std::width manipulator along with the std::left or std::right manipulators.
So you could set the width to the number of spaces, then print out one space. See also std::fill.

Edit 3: Vertical Centering
The vertical centering using the same formula:

Lines to print after = (lines in console) / 2; // Assuming your text is only 1 line. 

For portability, you can print half the lines to clear the junk, then print the text line, then print half the lines.

But since there is no standard for consoles, especially with windowing systems, you will have to get that information on the fly.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
1

thank you all for your input. I have no idea why my question was down voted. My bad if it was kind of a dumb question but that's why we are here right!? anyway, I figured out the answer, might not be the best but it worked :) I thought, I would share it with you. By the way, this is compiled in an UNIX environment.

#include <sys/ioctl.h>                                  //Use of binary forms tog et the terminal size
#include <stdio.h>
#include <string.h>

void writeScr(char *string, int rows, int cols);

int main()
{

    struct winsize w;                                   //struct winsize : will get the screensize width and height.
    ioctl(0, TIOCGWINSZ, &w);                           //TIOCGWINSZ, IOCtl to Get the WINdow SiZe.

    int columns = w.ws_col;                             //w.ws_col : number of columns from IOCTL 
    int rows = w.ws_row;                                //w.ws_row : number of rows from IOCTL


    writeScr("Hello world\n", w.ws_row, w.ws_col);


    return 0;
}

/*Functions*/

void writeScr(char *string, int rows, int cols)
{
    int vertl = rows/2;
    int hortl = 0;
    int stringLength = strlen(string) / 2;

    hortl = (cols - strlen(string))/2;                  //Calculate the center Horizontally

    for (int x = 0; x <= rows; x++)                     //For loop to print blank spaces
    {
        printf("\n");
        if (x == vertl)                                 //If x is in the middle (vertically centered), print the string
        {
            printf("\n%*s\n", cols / 2 + stringLength, string );            //Print string to the center horizontally
        }
    }
}
chichacail
  • 65
  • 1
  • 2
  • 6
0

Use the ncurses library, which was designed for this task. stdio will not (at least not easily) give you access to your terminal's capabilities; you can then overwrite arbitrary positions on your screen.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • There's also `pdcurses`, which supports some platforms that `ncurses` does not (notably Windows, among others). The API is almost the same (but `pdcurses` *is* missing some menu-related functionality that you're unlikely to miss anyways, at least for your uses). – Tim Čas Feb 10 '15 at 22:46
0

You can rely on the fact that text which goes off the right of the screen scrolls onto the left, so you can find out how many characters to add to repeatedly move off the right of the screen and onto the next line at the left of the screen and add it to your current calculation:

printf("%*s\n", (columns / 2 + stringLength)+((rows/2)*columns), string );
Chris
  • 2,655
  • 2
  • 18
  • 22