C Simple "Hello World" without ncurses?

Hello,

I am facing a distant machine, that has no ncurses library ( no curses.h, no ncurses_dll.h,... into the library).

What about low-level or alternative?
Note that links2 could be compiled, fairly, without this ncurses library for C.

how to do a simple ?
C:
mvprintw( 5,5, "hello world"); getch();

I found that termcap could maybe be used to display the classic "hello world" on row=5 col=5, but it requires ncurses anyway.

So, which solution would you have in mind?
 
What are you trying to accomplish? What is your goal?

If you are just trying to clear the screen, and print at position X,Y on the screen:
Output the ANSI escape sequence for clear screen (esc [ 2 J) followed by the escape sequence for move cursor to top of screen (esc [ 1 ; 1 H). Then print Y-1 newlines, and then X-1 spaces, and then "Hallo world". You can instead just move the cursor directly to the correct position with the "esc [ X ; Y H" sequence. This is very easily done in any programming language (the hardest part is getting the "esc" character into a string).

Why does this work? Because today, every terminal used in practice (today all terminals are terminal emulators running either on VGA or on a windowing system) supports ANSI escape sequences. Termcap was necessary in the 70s and 80s, when there were hundreds of incompatible ways of interfacing to terminals and controlling their screen. Through the normative power of the better solution (Digital Equipment's VT100 and VT2xx series of terminals, and their clones, which was then standardized by ANSI), today that incompatibility doesn't exist any more; we could just hardware ANSI escape sequences in everything.

Now, if you want to do a complex character-based GUI (with windows, box outlines), then curses (in its free and better implementation ncurses) is still a sensible solution; having to code all that yourself with ANSI sequences by hand is more work.
 
Here is a good example.

thank you for the example, as you see, I could clean up the code, but it needs more cleaning to make it as small as possible.

ESC reminds me a lot the old MS-DOS 3.3 manuals, that I read when younger... It seems that ncurses is a overkill to handle the terminal.


Code:
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include "term.h"
/*ANSI/VT100 Terminal using example */
#define home()             printf(ESC "[H") //Move cursor to the indicated row, column (origin at 1,1)
#define clrscr()        printf(ESC "[2J") //lear the screen, move to (1,1)
#define gotoxy(x,y)        printf(ESC "[%d;%dH", y, x);
#define visible_cursor() printf(ESC "[?251");
/* Set Display Attribute Mode    <ESC>[{attr1};...;{attrn}m */
#define resetcolor() printf(ESC "[0m")
#define set_display_atrib(color)     printf(ESC "[%dm",color)


void npaint() {
    char buffer[22];
        strncpy( buffer, "Hello World" , 22 );
    set_display_atrib(B_BLUE);
    while (1)
        {
        gotoxy(5,3);
            puts(buffer);
        fflush(stdout);
        sleep(100000);
    }
}



int main (void)
{
    home();
    clrscr();
    npaint();
    return 0;
}
 
screen(4) is a nice resource for ANSI escape sequences, btw.


Here is a getch():

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <err.h>

static struct termios tt_old;

/*
* Switch terminal into non-canonical mode.
*/
int
rawtty()
{
    static struct termios tt;

    if (tcgetattr(STDIN_FILENO, &tt) == -1)
        return (-1);
    tt_old = tt;
    tt.c_lflag &= ~(ICANON | ECHO);
    tt.c_cc[VTIME] = 0;
    tt.c_cc[VMIN] = 1;

    return (tcsetattr(STDIN_FILENO, TCSANOW, &tt));
}

int
unrawtty()
{
    return (tcgetattr(STDIN_FILENO, &tt_old));
}

int
getch()
{
    char c;

    if (read(STDIN_FILENO, &c, sizeof(c)) == -1)
        return (-1);
    return (c);
}

int
main()
{
    int c;
  
    if (rawtty() == -1)
        err(1, "rawtty()");
    (void)fprintf(stderr, "Press 'q' to quit\n");
    while ((c = getch()) > 0 && c != 'q')
        ;
    (void)unrawtty();

    return (0);
}
 
awesome. thank you !

Code:
#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int main( )
{
  struct termios oldt,
                 newt;
  int            ch;
  tcgetattr( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
  return ch;
}
 
There is now a small attempt to clean it up, slowly to make a clock and later, a small library.

Here the code (with h file into to make all in one) :
Code:
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

//#include "term.h"

#ifndef __TERM_EXAMPLE__
#define __TERM_EXAMPLE__

#define ESC "\033"

//Format text
#define RESET         0
#define BRIGHT         1
#define DIM            2
#define UNDERSCORE    3
#define BLINK        4
#define REVERSE        5
#define HIDDEN        6

//Foreground Colours (text)

#define F_BLACK     30
#define F_RED        31
#define F_GREEN        32
#define F_YELLOW    33
#define F_BLUE        34
#define F_MAGENTA     35
#define F_CYAN        36
#define F_WHITE        37

//Background Colours
#define B_BLACK     40
#define B_RED        41
#define B_GREEN        42
#define B_YELLOW    44
#define B_BLUE        44
#define B_MAGENTA     45
#define B_CYAN        46
#define B_WHITE        47

#endif /*__TERM_EXAMPLE__*/
/*ANSI/VT100 Terminal using example */


#define home()             printf(ESC "[H") //Move cursor to the indicated row, column (origin at 1,1)

#define clrscr()        printf(ESC "[2J") //clear the screen, move to (1,1)

#define gotoxy(x,y)        printf(ESC "[%d;%dH", y, x);
#define visible_cursor() printf(ESC "[?251");

/*
Set Display Attribute Mode    <ESC>[{attr1};...;{attrn}m
*/
#define resetcolor() printf(ESC "[0m")
#define set_display_atrib(color)     printf(ESC "[%dm",color)


void frame_draw ()
{
    home();
    set_display_atrib(B_BLUE);
                //            123456789012345678901
               //puts(    "┌─────────┐┌─────────┐\n" //0

            //"├─────────┤\n" //4
               puts(    "┌─────────┐\n" //0
            "│         │\n" //1
            "│         │\n" //2
            "│         │\n" //3
            "└─────────┘"); //9

/*
            "│         │┌─────────┐\n" //4
            "│         ││         │\n" //1
            "│         ││         │\n" //2
            "│         ││         │\n" //3
            "│         │├─────────┤\n" //4
            "│         ││         │\n" //5
            "│         ││         │\n" //6
            "│         ││         │\n" //7
            "│         ││         │\n" //8
            "└─────────┘└─────────┘\n" //9
            "┌────────────────────┐\n" //10
            "│                    │\n" //11
            "└────────────────────┘");  //12
     */

    resetcolor();
}

void print_port_bits (unsigned char port) {
    int i;
    unsigned char maxPow = 1<<(8-1);
    set_display_atrib(B_BLUE);
    set_display_atrib(BRIGHT);
    for(i=0;i<8;++i){
        // print last bit and shift left.
        gotoxy(2,2 + i);
        if (port & maxPow) {
            set_display_atrib(F_GREEN);
            printf("pin%d= on ",i);
        } else {
            set_display_atrib(F_RED);
            printf("pin%d= off",i);           
        }
        port = port<<1;
    }
    resetcolor();
}


void print_accelerometer(float * a) {
    int i;
    const char * coordinate = "XYZ";
    set_display_atrib(B_BLUE);
    set_display_atrib(BRIGHT);
    int display_atrib = F_RED;
    set_display_atrib(display_atrib);
    for (i = 0; i < 3; i++) {
        set_display_atrib(display_atrib + i);
        gotoxy(13,2+i);
        printf("A%c=%+1.3f", coordinate[i], a[i]);
    }
    

    resetcolor();
}



void print_alarm (int alarm_error)
{
    gotoxy(2,12);
    gotoxy(1,12-6);
    if (alarm_error) {
        set_display_atrib(BRIGHT);
        set_display_atrib(B_RED);
        printf("        ERROR       ");
    } else {
        set_display_atrib(BRIGHT);
        set_display_atrib(B_GREEN);
        //printf("         OK         ");
        printf(" | TIME |  ");
    }
}


void print_time_date (struct tm* tm_info)
{
    char buffer[12];
    set_display_atrib(BRIGHT);
    set_display_atrib(B_BLUE);
    strftime(buffer, 12, "%d.%m.%y", tm_info);
    gotoxy(13,7)
    gotoxy(2,2);
    puts(buffer);
    strftime(buffer, 10, "%H:%M:%S", tm_info);
    gotoxy(13,8)
    gotoxy(2,3);
    puts(buffer);
    resetcolor();
}

unsigned char rol(unsigned char  a)
{
    return (a << 1) | (a >> 7);
}



void controller_emulator ()
{
    unsigned char  port = 0x01;
    int alarm_counter = 0;
    time_t timer;
    struct tm* tm_info;
    srand(time(NULL)); 
    while (1) {
        float a[3] = {0.0, 0.0, 0.0};
        int i;
        for (i=0; i<3; i++) {
            int r = rand() % 101 + (-50);
            a[i] += (float)r / 1000;
        }
        if (alarm_counter < 30) {
            print_alarm(0);
        }
        if ((alarm_counter < 60) && (alarm_counter >= 30)) {
            //print_alarm(1);
        }
        if (alarm_counter > 60) {
            alarm_counter = 0;
        }
        alarm_counter++;
        time(&timer);
        tm_info = localtime(&timer);
//********************************//
        //print_accelerometer(a);
        //print_port_bits(port);
        print_time_date(tm_info);
//********************************//
        port = rol(port);
        gotoxy(1,18);
        fflush(stdout);
        usleep(100000);
    }
}


int main (void)
{
    home();
    clrscr();
    frame_draw();
    controller_emulator();
    return 0;
}
 
Back
Top