simple scanf issue ?

Hello everyone,

I hope someone is awake to help me on this..

hey How can I do something like this:

The user is asked is asked to enter an int value, but I want to provide a default value on stdout, which they can back space and change it to whatever they want..

for e.g:

Enter the number of worker threads: 1

so here, the words "Enter the number of threads" is a printf statement. 1 is the default value. But the user should be able to backspace the 1 and enter whatever he wants.

Can i do something like this in C ?

Thank you..

hmm on googling, it seems that there is no such a way !

Actually you can do it in an xterm windowed environment using a textbox widget -but not in straight C ....

It can be done in straight C, although admittedly it is not exactly a piece of cake. I've been working on this all day... it's still a little crude, but it works well enough to show how to do it. I'm too tired to refine further. So...

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <termios.h>

// buffer is an area for the characters to be stored
// max is how big the field is
// init is optional initial value for field
// no 0 will placed after the returned characters
// if + return value is the number of chars returned
// if 0 is returned, user provides no input
// if - user aborted input by typing his intr or quit character
// if user types his kill character the field is reset to init value


int get_field(char *buffer, int max, char *init) {
        struct termios orig, now;
        int col, save_col, i, count, done, abort;
        char *pinit;
        char rdbuff[10], *prdbuff;
        char *dbuff, *pdbuff;
        char *bsbuff1, *pbsbuff1;
        char *bsbuff2, *pbsbuff2;
        char dummy[]="";

// If we get a null pointer for init, replace it with a valid pointer to an empty string.
        if(!init)init=dummy;

// Let's say our field is 10 characters long.  We then grab 30 consecutive bytes.
// Bytes 0 - 9 are bsbuff1 (backspace buffer) and are filled with backspace chars
// Bytes 10 - 19 are dbuff (display buffer) and reflect what is on the screen
// Bytes 20 - 29 are bsbuff2 (backspace buffer) and are filled with backspace chars
// So by carefully picking a starting byte and a length, we can backspace over what
// we have displayed, overwrite the display, and position the cursor in one write
// system call.
// These are not strings...no zero terminator is present.

        bsbuff1 = (char *) malloc(max*3);
        dbuff = bsbuff1+max;
        bsbuff2 = dbuff+max;
        col=0;
        for(i=0, pdbuff=dbuff, pbsbuff1=bsbuff1, pbsbuff2=bsbuff2, pinit=init; i<max; i++,pdbuff++) {
                *pbsbuff1++ = '\b';
                *pbsbuff2++ = '\b';
                if (*pinit) {
                        *pdbuff=*pinit++;
                        col++;
                } else {
                        *pdbuff=' ';
                }
        }
        fflush(stdout);
        write(1,dbuff,2*max-col);
        save_col=col;

// Set up tty
        tcgetattr(0,&orig);
        now=orig;
        now.c_lflag &= ~(ISIG|ICANON|ECHO);
        now.c_cc[VMIN]=10;
        now.c_cc[VTIME]=2;
        tcsetattr(0,TCSANOW, &now);

// Loop to read characters.  We read 10 chars at a time because
// function keys return a sequence of characters and we want to ignore them all.

        abort=0;
        done=0;
        while(!done) {
                count = read(0,rdbuff,10);
                for(i=0, prdbuff=rdbuff; i<count && !done; prdbuff++,i++) {
                        if(*prdbuff  == now.c_cc[VERASE]) {
                                if(col) {
                                        col--;
                                        write(1,"\b \b",3);
                                } else {
                                        write(1,"\a",1);
                                }
                        } else if(*prdbuff  == now.c_cc[VKILL]) {
                                for(i=0, pdbuff=dbuff, pinit=init; i<max; i++,pdbuff++) {
                                        if (*pinit) {
                                                *pdbuff=*pinit++;
                                        } else {
                                                *pdbuff=' ';
                                        }
                                }
                                write(1,bsbuff1+max-col,2*max+col-save_col);
                                col=save_col;
                        } else if (*prdbuff == '\033') {
                                write(1,"\a",1);
                                i=count;
                        } else if (*prdbuff == '\n') {
                                done=1;
                        } else if (*prdbuff == '\r') {
                                done=1;
                        } else if(*prdbuff  == now.c_cc[VINTR]) {
                                done=1;
                                abort=1;
                        } else if(*prdbuff  == now.c_cc[VQUIT]) {
                                done=1;
                                abort=1;
                        } else {
                                write(1,prdbuff,1);
                                dbuff[col++]=*prdbuff;
                        }


                }
        }

// Prepare for return

        tcsetattr(0,TCSANOW, &orig);
        free(bsbuff1);

// Return to caller

        if(abort) {
                return -1;
        } else {
                for(i=0; i<col; i++) {
                        buffer=dbuff;
                }
                return col;
        }
        return 0;
}



int main(int argc, char *argv[])  {

        char ibuf[80];
        int iret;
        fputs("generic prompt -", stdout);
        if ((iret = get_field(ibuf, 10, "123" )) > 0) {
                ibuf[iret]=0;
                printf("\n ibuf is now \"%s\"  %d\n", ibuf, iret);
        } else if (iret == 0) {
                printf("\n no input \n");
        } else {
                printf("\n input was aborted\n");
        }
        exit(0);
}

You can implement this in similar 'standard' way, e.g

Enter the number of worker threads (1):

If user enters nothing default value (1) is used.