Using fgetc() to read control characters

This is a discussion on Using fgetc() to read control characters within the C Programming forums, part of the General Programming Boards category; I am unable to read control characters from stdin using fgetc(). Are there ascii codes for things like ^c (ctrl-c) ...

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    55

    Using fgetc() to read control characters

    I am unable to read control characters from stdin using fgetc(). Are there ascii codes for things like ^c (ctrl-c) that I can use to compare the return value of fgetc() with? Thanks.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Reading CTRL-C with fgetc() isn't trivial, since CTRL-C is "special" by most OS's. There are usually ways that you can "make the OS send CTRL-C to the application", or a way to read the input at a lower level so that CTRL-C is not entering the OS's path for "kill the app if this happens". But these methods are both OS-dependent, and not entirely simple.

    Assuming you have a method to read control chars, they are pretty trivial to translate. Just take the regular alphabetical character and subtract 64, e.g. CTRL-A == 'A'-64 == 1.

    What are you actually trying to achieve?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    I have to write a simple line editor that is in non-canonical mode, thus the program has to process the input instead of the terminal. In my program, ^C among others has to do specific things with the input. I have turned off the ISIG bit to avoid terminating the program. But I have not been able to detect the ^C .

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you set the mode right [and no, don't ask me what EXACTLY is right here], you should be able to read control chars with fgetc() - it's not fgetc() that decides what you get or not get, but rather the low-level keyboard input uses CTRL-C as a special character.

    Are you sure that you don't need to set termio c_cc[VINTR] = 0 as well?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    I have gone through the mode bits again, but the program is not detecting ^c. Here is the part of the code:

    Code:
     term_attributes.c_lflag &= ~ECHO ;  
     term_attributes.c_lflag &= ~ICANON;
     term_attributes.c_lflag &= ~ISIG; 
    
     term_attributes.c_cc[VMIN] = 1;
     term_attributes.c_cc[VINTR] = 0;
    
     tcsetattr(fileno(TERMINAL),TCSANOW, &term_attributes); 
     
      while (  c=fgetc(stdin)  )
      {
        if( c == '\b')
          fputs("Backspace", stdout);
    
        if(c == '\n')
        {
          tcsetattr(fileno(TERMINAL),TCSANOW,&orig_attributes); /* restore saved settings    */
          exit(1);
        }
    
        if( c  ==  '3')
          fputs("Control C", stdout);
    
        fputc(c,stdout);
      }

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
        if( c  ==  '3')
          fputs("Control C", stdout);
    That should be:
    Code:
       if( c  ==  3)
          fputs("Control C", stdout);
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    55
    Thanks matsp. I also just figured out what the problem was.

    Code:
     term_attributes.c_lflag &= ~ECHO ;  
     term_attributes.c_lflag &= ~ICANON;
     term_attributes.c_lflag &= ~ISIG;
    should be
    Code:
     term_attributes.c_lflag &= ~(ECHO | ICANON | ISIG) ;
    I am now getting the ^ characters.
    Last edited by Bnchs; 03-19-2008 at 10:44 AM.

  8. #8
    Registered User
    Join Date
    Mar 2008
    Posts
    3
    How about using, bioskey() function???

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I doubt very much that Linux supports bioskey(), as it's only available in old DOS-compilers, particularly Turbo C.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (Multiline) Edit Control Limit
    By P4R4N01D in forum Windows Programming
    Replies: 9
    Last Post: 05-17-2008, 11:56 AM
  2. read characters till white space
    By ashok449 in forum C Programming
    Replies: 2
    Last Post: 03-08-2008, 02:56 AM
  3. Replies: 3
    Last Post: 02-29-2008, 12:29 PM
  4. "sorting news" assignment
    By prljavibluzer in forum C Programming
    Replies: 7
    Last Post: 02-06-2008, 05:45 AM
  5. Using Control Characters in Unix
    By jharley in forum C Programming
    Replies: 2
    Last Post: 12-06-2001, 08:17 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21