Home > Back-end >  C read() function is reading in nothing
C read() function is reading in nothing

Time:01-27

What I want this to do is get a char input which correlates to some menu options. If they enter o, they enter the filename to be opened. My input is just 'o' followed by ctrl d and it seems like the read() in getFileName is just reading in nothing. I thought it was reading in the eof marker but I tried setting the buffer to 2 and having menuOpt be an array of 2 chars but that didn't work either so I don't think it's that.

int main(){
    char menuOpt;
    int readRes;
    char fileName[BUFF_FILENAME] = "";
    int fd;

    //displayMenu(0);
    
    while((readRes = read(STDIN_FILENO, &menuOpt, 1)) > 0){
        if(menuOpt == 'o'){
            fprintf(stdout, "Enter the file name: ");
            if(getFileName(fileName) > 0){
                readFile(&fd, fileName);
            }
        } 
        // else if(menuOpt == 'd'){
        //     fprintf(stdout, "do something");
        // } else {
        //     fprintf(stderr, "Invalid input\n");
        // }
    }

    printf("%d\n", readRes);

    return 0;
}

int getFileName(char fileName[BUFF_FILENAME]){
    int r = read(STDIN_FILENO, fileName, BUFF_FILENAME);
    printf("\nBytes read = %d\n", r);
    printf("and filename is %sx\n", fileName);
    if(r == 0){
        fprintf(stdout, "No file name entered\n");
    } else if(r < 0){
        fprintf(stderr, "There was an error reading the file name\n");
    } 

    return r;
}

if my input is JUST the char 'o' followed by ctrl d I get this:

Current output mode: ASCII
ENTER:
"o" to enter a file name
"d" to select display mode
"x" to exit
oEnter the file name: 
Bytes read = 0
and filename is x
No file name entered

...and then it waits for some other input from the while loop in main().

I am not entering anything after "Enter the file name:" it's just reading what seems like nothing. Also the o just before "Enter the file name:" isn't a typo, that's just my input.

CodePudding user response:

Here is example of how set the terminal to raw mode and read a byte.
You want to restore the previous mode before exit, say, using atexit().

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

static struct termios old;

void cleanup() {
    tcsetattr(STDIN_FILENO, 0, &old);
}

int main() {
    tcgetattr(STDIN_FILENO, &old);
    atexit(cleanup);

    struct termios new = old;
    cfmakeraw(&new);
    tcsetattr(STDIN_FILENO, 0, &new);
    char ch;
    read(STDIN_FILENO, &ch, 1);
    printf("%c\n", ch);
}

It is probably more natural to use getchar() instead of read() in this case:

   int ch = getchar();
  • Related