0

Hi i was reading K & R C where in the example to use getchar we have to press RET to end the input. Is there any way to change the input so that I can change the newline as the input separator to a comma. I use a Linux Mint . 64 bit. I get the input by running the program as ./Hello.o

Eg.

Hello world<RET>

but as I type a comma or dot the input should end

Eg.

Hello world, //End of input due to comma 

Is there any way to change new line to another character to comma

xtreak
  • 1,376
  • 18
  • 42
  • 1
    I'm not sure to entirely understand the question (I'm guessing parts of it). On Linux, when `stdin` is a tty (see `isatty` function) -i.e. when reading from th terminal, the buffering is partly done by the kernel. And the answer to your question is operating system specific. – Basile Starynkevitch Dec 21 '13 at 12:40
  • I updated the OS as linux mint 64 bit @BasileStarynkevitch – xtreak Dec 21 '13 at 12:42
  • I don't understand what you really want to do, and I guess you don't either. Perhaps your goal is much more difficult to achieve that what you believe.... – Basile Starynkevitch Dec 21 '13 at 12:54
  • Well when you enter the input to the terminal you have to press enter to end the input and then read it char by char from the buffered input. But I would like to change the \n to a comma wherein if we type Hello world, the input ends . @BasileStarynkevitch – xtreak Dec 21 '13 at 12:59
  • In perl we have special variables like $' where we can change is there any special variable for the input separator in C. – xtreak Dec 21 '13 at 13:01
  • As I answered, it is difficult to achieve. And I am not sure at all that Perl's `$'` will avoid pressing the *enter* key! – Basile Starynkevitch Dec 21 '13 at 13:07
  • What is the real context of the question (what application are you coding)? How important is that to you? Are you willing to work for weeks to achieve that goal? Can't you do otherwise?? – Basile Starynkevitch Dec 21 '13 at 13:08
  • I was learning perl and was wondering if C too has special variables like perl thats al. Ok thanks @BasileStarynkevitch – xtreak Dec 21 '13 at 13:08
  • Setting `$/` in perl (`$'` has nothing to do with the input separator, and I believe you mean `$/`) will not accomplish what you want. You need to put the terminal into raw mode. – William Pursell Dec 21 '13 at 13:16
  • I just used $' as an example for special variable @WilliamPursell . Thanks but it seems way too difficult for a beginner. – xtreak Dec 21 '13 at 13:28

3 Answers3

2

It depends what function you want to use. For example, if you want to use getdelim you can provide a delimiter argument

ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

for example:

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

int main()
{
    char * lineptr = malloc(1000 * sizeof(char));
    size_t n = 1000;
    /*type something in that ends in a comma*/
    getdelim(&lineptr, &n, ',', stdin);
    /*print the result*/
    printf("%s\n", lineptr);
    free(lineptr);
    return 0;
}

Note that this still requires you to press enter but everything after the comma will be discarded.

edit

Maybe you could try something like this?

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

/* Use this variable to remember original terminal attributes. */

struct termios saved_attributes;

void
reset_input_mode (void)
{
    tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
}

void set_input_mode (void)
{
    struct termios tattr;
    char *name;

    /* Make sure stdin is a terminal. */
    if (!isatty (STDIN_FILENO))
    {
        fprintf (stderr, "Not a terminal.\n");
        exit (EXIT_FAILURE);
    }

    /* Save the terminal attributes so we can restore them later. */
    tcgetattr (STDIN_FILENO, &saved_attributes);
    atexit (reset_input_mode);

    /* Set the funny terminal modes. */
    tcgetattr (STDIN_FILENO, &tattr);
    tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
    tattr.c_cc[VMIN] = 1;
    tattr.c_cc[VTIME] = 0;
    tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
}

int main()
{
    char c;

    set_input_mode ();

    while (1)
    {
        read (STDIN_FILENO, &c, 1);
        if (c == ',')
            break;
        else
            putchar (c);
    }

    return 0;
}

This program will receive input until a comma. I can't take any credit for it, I found this link on noncanonical input.

Community
  • 1
  • 1
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • I need to press RET to end the input as Hello world, hai gives Hello world, but as I press , near the d in world the input must end @Tom Fenech – xtreak Dec 21 '13 at 12:57
  • @xtreak I just found something online that might help you – Tom Fenech Dec 21 '13 at 13:16
1

I would first read the standard input line by line using getline(3). Then you can do your own tokenizing on that line, e.g. with sscanf(3), strtok(3) or other means (e.g. using strchr(3) appropriately). See this answer for some code (but getline won't enable you to avoid pressing the return key, because the kernel tty subsystem is processing that key, unless you do raw keyboard input which is really difficult).

On Linux, you might be interested in using readline(3) from the readline library (which is quite powerful, so learn more about it). Maybe you could use the ncurses library.

Be aware that terminals are very complex things (or abstractions), mostly for historical reasons. Read with care the tty demystified page, and the Keyboard and Console HowTo.

Avoiding pressing the enter or return key is surprisingly difficult on Unix systems (and probably on others too!) because the kernel (and not only the application or its libc i.e. <stdio.h> functions) is usually buffering the input line. To avoid that, you need to do very low level and difficult programming (which could take you several weeks of work). Read first Advanced Linux Programming.

So instead of doing all the difficult coding by yourself, take several days to learn how to use readline (or maybe ncurses). Even with the help of such libraries, it is not that easy!

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

You can use getch() function available in ncurses library.

You do no need to press Enter after each character input, therefore you can scan input in a while loop using getch() unless you get a , or any special character you want.

0xF1
  • 6,046
  • 2
  • 27
  • 50