LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-10-2010, 02:28 PM   #1
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Rep: Reputation: 133Reputation: 133
C: behaviour of getchar() after a print statement that ends in a whitespace???


Maybe a beginner's question but then I have been learning C for only two days...

How do I make getchar() skip a leading space? The situation I am looking is this: I print a prompt that ends in a space
printf("Input: ");
and then when I use getchar() to read the text that was typed after the prompt, it appears to process the trailing space as a leading space that belongs to the input.
Could anyone explain why? And how can the space be skipped, preferably without inserting code that explicitly checks whether I'm reading the first character or not. I have already found out that I can skip such a space using scanf
scanf (" %c", &ch);
where the leading space in the format string eliminates leading spaces from the input string. That is the sort of thing I have in mind.
 
Old 07-10-2010, 04:00 PM   #2
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by jay73 View Post
Maybe a beginner's question but then I have been learning C for only two days...

...when I use getchar() to read the text that was typed after the prompt, it appears to process the trailing space as a leading space that belongs to the input. ...
'getchar' is buffered, i.e. new characters are seen only after you enter newline ('\n').

So, if, for example, you want to enter 'a', in fact you need to enter 'a', '\n'. So after the first call to 'getchar' you'll get 'a' (that's what you expect), but on the second call (suppose, you wanted to enter 'b') instead of 'b' you'll first get the '\n' you've entered after 'a', and only on the third call you'll get 'b', but again you'll have yet another '\n' in the buffer.

Try 'fread' instead.
 
Old 07-10-2010, 07:16 PM   #3
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 179Reputation: 179
Quote:
Originally Posted by Sergei Steshenko View Post
Try 'fread' instead.
That won't help. The problem is not fread() versus getchar(); you need to use termios to make your data unbuffered. Then you can use either getchar() or fread().

To observe how fread() acts buffered under ordinary circumstances, run this shell script:
Code:
cat > 1.c <<EOD; rm -f 1; gcc -Wall -Werror 1.c -o 1; ./1
#include <stdio.h>

int main(void)
{
  int           linefeed_count;

  unsigned char buffer[4];

  fprintf(stderr,"a prompt: ");

  linefeed_count=0;

  for(;;)
  {
    if(fread(buffer,1,1,stdin)<1)
    {
      break;
    }

    printf("got 0x%02X",buffer[0]);

    if((buffer[0]>=' ') && (buffer[0]<='~'))
    {
      printf(" %c",buffer[0]);
    }

    printf("\n");

    if(buffer[0]=='\n')
    {
      linefeed_count++;
    }

    if(linefeed_count>=2)
    {
      break;
    }
  }

  return 0;

} /* main() */
EOD
If you run the program and enter "x", and press the <Enter> key, and then "b", and press the <Enter> key, you'll get output like this:
Code:
a prompt: x
got 0x78 x
got 0x0A
y
got 0x79 y
got 0x0A
 
Old 07-11-2010, 07:15 AM   #4
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by wje_lq View Post
That won't help. The problem is not fread() versus getchar(); you need to use termios to make your data unbuffered. Then you can use either getchar() or fread().
...
Well, we still have 'man 2 read' .
 
Old 07-11-2010, 06:57 PM   #5
wje_lq
Member
 
Registered: Sep 2007
Location: Mariposa
Distribution: FreeBSD,Debian wheezy
Posts: 811

Rep: Reputation: 179Reputation: 179
We need termios for this. We really, really do.
Quote:
Originally Posted by Sergei Steshenko View Post
Well, we still have 'man 2 read' .
Well, you're right, we do, but it won't help here. We still get the same output with the same input, but run against this shell script:
Code:
cat > 1.c <<EOD; rm -f 1; gcc -Wall -Werror 1.c -o 1; ./1
#include <stdio.h>
#include <unistd.h>

int main(void)
{
  int           linefeed_count;

  unsigned char buffer[4];

  fprintf(stderr,"a prompt: ");

  linefeed_count=0;

  for(;;)
  {
    if(read(STDIN_FILENO,buffer,1)<1)
    {
      break;
    }

    printf("got 0x%02X",buffer[0]);

    if((buffer[0]>=' ') && (buffer[0]<='~'))
    {
      printf(" %c",buffer[0]);
    }

    printf("\n");

    if(buffer[0]=='\n')
    {
      linefeed_count++;
    }

    if(linefeed_count>=2)
    {
      break;
    }
  }

  return 0;

} /* main() */
EOD
 
Old 07-13-2010, 01:06 AM   #6
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
Thanks for your suggestions but I'm afraid I don't see how they answer my question. Like I said, the problem is that part of my output is being considered as input:
Code:
printf("Input: ");  //print "Input: " prompt
char ch = getchar();  //read input entered at the prompt
If I run the code and enter, say, an 'a', I would expect ch to hold the value 'a'. But it doesn't, it contains a space. The only reason I can think of is that somehow the trailing space of the prompt (there is a space after the colon) is being treated as input. But why?
 
Old 07-13-2010, 01:27 AM   #7
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
It does not take that trailing space (or at least I'm 99.99% sure that it does not)

Code:
#include <stdio.h>

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

    printf("Input: ");
    ch=getchar();

    printf("ch = 0x%X\n", ch);
    return 0;
}
Code:
wim@btd-techweb01:~/progs/lq819120$ gcc -Wall lq819120.c -o lq819120
wim@btd-techweb01:~/progs/lq819120$ ./lq819120
Input: A
ch = 0x41
wim@btd-techweb01:~/progs/lq819120$
Your problem might be that your terminal uses a characterset that uses multiple bytes instead of single byte ASCII (not sure what it is called).
 
Old 07-13-2010, 02:09 AM   #8
jay73
LQ Guru
 
Registered: Nov 2006
Location: Belgium
Distribution: Ubuntu 11.04, Debian testing
Posts: 5,019

Original Poster
Rep: Reputation: 133Reputation: 133
Hi Wim,

Terminal uses UTF.8. When I run your piece of code, I also get 41 hex so the problem must lie elsewhere. I think I'll need to take a better look at the code that was producing the problem. It seems quite likely that some method call before the printf statement leaves a new line in the buffer.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How do I print lots of html code within a PHP if statement beebopbogo Programming 2 08-29-2009 07:27 PM
Strange if statement behaviour when using bash/bash script freeindy Programming 7 08-04-2008 06:00 AM
to print the files that ends with .sh extension naveensankineni Programming 4 03-15-2008 08:19 PM
Bash: Print usage statement & exit; otherwise continue using Bash shorthand operators stefanlasiewski Programming 9 02-07-2006 05:20 PM
Print statement never executed Linh Programming 3 08-14-2003 12:46 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:14 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration