user2977378
user2977378

Reputation: 49

Adding support for newlines (\n) in C

I have written a simple OS which I am compiling using QEMU in Linux. The terminal is printing a simple message on the screen ("Hello World\n"), however, the new line character (\n) is producing a strange character rather than inserting a new line after the message.

Here is the code I have written for putchar:

void putchar(char c) {
    putentryat(c, color, column, row);
    if (++column == WIDTH) {
        column = 0;
        if (++row == HEIGHT) {
            column = 0;
        }
    }
}

Main function simply calling a writestring function which displays the message as shown in the below code.

void main() {
    initialize();
    writestring("Hello World\n");
}

At the moment the n is printing out garbage character as stdio.h is not supported by the program. I have tried adding putchar('\n'); in putchar function after putentryat(...) but I am still getting the problem.

If somebody can provide tips on how I can resolve this problem I would greatly appreciate it.

Upvotes: 1

Views: 1109

Answers (3)

Jabberwocky
Jabberwocky

Reputation: 50911

Maybe you need this:

void putchar(char c){
   if (c == '\n') {
     column = 0;
     if (++row == HEIGHT) {
        // perform scroll 
     }
   }
   else  
      putentryat(c, color, column, row);

   if (++column == WIDTH) {
     column = 0;
     if (++row == HEIGHT) {
       // perform scroll
       column = 0;
     }
   }
}

Upvotes: 4

chqrlie
chqrlie

Reputation: 145307

The terminal handles some characters such as \n specifically to perform specific tasks:

  • \n causes the cursor to move down one line, and possibly to go back to the leftmost column (column = 0 in your case).
  • \r should cause the cursor to move to the leftmost column on the current line.
  • \t moves the cursor right to the next TAB stop, usually a multiple of 8 positions.
  • \f could erase the screen and move the cursor to the home position.
  • \a could cause the speaker to produce a beep or the screen to blink.

All these actions are performed instead of displaying a character at the current cursor position. You must test the character value specifically to perform the special action instead of displaying the character.

Here is an example:

void term_putchar(int c) {
    switch (c) {
      case '\r':
        column = 0;
        break;
      case '\n':
        column = 0;
        row++;
        break;
      case '\t':
        column = (column + 8) / 8 * 8;
        if (column >= WIDTH) {
            column -= WIDTH;
            row++;
        }
        break;
      case '\f':
        term_erase_screen();
        column = row = 0;
        break;
      case '\a':
        term_beep();
        break;
      default:
        putentryat(c, color, column, row);
        if (++column == WIDTH) {
            column = 0;
            ++row;
        }
        break;
    }
    if (row == HEIGHT) {
        if (term_page_mode) {
            row = 0;
        } else {
            term_scroll_screen_up();
            row--;
        }
    }
    /* should update the blinking cursor on the screen screen */
}

int putchar(int c) {
    if (output_to_terminal) {
        term_putchar(c);
    } else {
        /* output to file? */
    }
    return c;
}

Note that real terminals have far more special characters to control output, screen handling, colors, cursor movement, flow control, etc. In addition to specific characters, they use escape sequences (\e followed by other characters).

Upvotes: 3

pmg
pmg

Reputation: 108986

// ...
if (c == '\n') {
    column = 0;
    row++;
    // do not putentry
}
// ...

Upvotes: 3

Related Questions