hi there)
guys , please tell me - is there any way to check that the standart input is empty or no.
big thanks in advance)

Recommended Answers

All 27 Replies

Try using a file and assigning to stdin?

/*
* The structure underlying the FILE type.
*
* Some believe that nobody in their right mind should make use of the
* internals of this structure. Provided by Pedro A. Aranda Gutiirrez
* <paag@tid.es>.
*/
#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;(MinGW Include: stdio.h).

#include <stdio.h>

int main(void)
{
    FILE *pFile ;
    int i ;

    pFile = stdin ;
    i = (int) sizeof (stdin) ;
    printf("%d bytes in stdin\n", i) ;
    
    for (i=0 ; pFile->_ptr[i]; i++)
	printf("%c", pFile->_ptr[i]) ;

    printf("\n%d count, %d bufsiz\n", pFile->_cnt, pFile->_bufsiz) ;
    return 0 ;
}

is there any way to check that the standart input is empty or no.

There's no portable way to do this without actually blocking for input. What OS and compiler are you using, and why do you think you need that behavior?

commented: +++ +3

Try looking inside what's inside stdin. It's just a buffer that has a memory address.
Is there a reason why you can't peek around?

#define stdin (&_iob[STDIN_FILENO]) (MinGW: Stdio.h)

In my situation i what to get stdin (stream from console) in empty condition , it is possible to use

fflush();

, but I've heared that it has nonstandart behavior. So to clean console input buffer I use =

while (getchar() != '\n');

- but this code 'll stop program when the input was empty primordially.
This stopping - isn't a good moment - so I need to check the buffer condition.

As I understand - i should check is the pointer in stream structure NULL ?))

my compiler - is Pelles C . I need code for both of linux and windows (and the standart behavior - what a beautiful word.....)

code example =

int main()
	 { 
	   char ch;
                printf("\n%s","please specify a one symbol" ); /* but user've put "dgfhj3  \n"  */
                ch = getchar();
   /*in buffer we have "gfhj3  \n"*/
		 mainmenu();
             
   /*in buffer we have "gfhj3  \n"*/
	return 0;
	   
	 }
int mainmenu(void)
  {
     char ch; 
	 char* mtext = " Please specify the number of the task. \n * You can choose on number from set = {1} \n * Specify \"0\" to exit\n" ;
	 char* errmes = " Error(!) = Main menu does not support this command.\n Make sure that your task number is from menu set of commands and try again. " ;
	 
	fflush(stdin); /* clear the input - stdin or use while (getchar() != '\n'); - but this'll stop program*/
       printf("\n%s",mtext );
       ch = getchar();
	
	 switch(ch)
     {
		case '0': exit(0);  
		case '1': exit(0); break;
		default: printf("\n%s\n", errmes);
	 }	
   return 0; 
  }

as I uderstand from hkdani example the way th check stdin is =

if  (!sizeof(stdin))

but the compiler this code is unreachable =

if  (!sizeof(stdin))  while (getchar() != '\n');
if  (!sizeof(stdin))  while (getchar() != '\n');

stdin is just a pointer to a struct _iobuf, so the sizeof(stdin) will always return the size of a pointer variable(4 bytes). So your flushing mechanism

while (getchar() != '\n');

won't even execute.

- but this code 'll stop program when the input was empty primordially.

yes, so just press the "enter" key if you want to get rid of the "stopping moment".But then after we'll come to the same question Narue asked-

There's no portable way to do this without actually blocking for input and why do you think you need that behavior?

I would say that you need to test for what the user has done. Not for what he hasn't done. The functions that use stdin take care of initializing the stdin buffer. Your job is to check what the user has put into the buffer after your function calls for use to stdin.

If you really want to know what's going on, find the source code for getchar() or whatever function you're calling to check the input from stdin. That should show you what takes place before you prompt the user for information from the keyboard.

There's no need to reinvent the wheel, if you have one already.

commented: ++++++++ +3

hm. but may be I should reformulate the question - if there's no universal way to check that the stdin is empty - may be there's a way to detect , that the getchar() - or something like it (fgets() for ex.) wait an user action and break it ?

find the source code for getchar()

in C ? hkdani , how can I get it - tell please)

Microsoft gives it you. Borland gives theirs for the common run time. Usually, it's in the VC dircectory usually called something appropriately like src. And I'm sure that Gnu GCC gives it to you. It is open source.

You could use WinDbg, gdb (Gnu debugger), td32 (Borland's command line debugger) and step through, step into the source code and see for yourself. You can check the actual assembly language being used as your program executes. But that's another topic..............................

hm. but may be I should reformulate the question - if there's no universal way to check that the stdin is empty - may be there's a way to detect , that the getchar() - or something like it (fgets() for ex.) wait an user action and break it ?

in C ? hkdani , how can I get it - tell please)

I'll reiterate: why do you need this behavior? If you truly need it then there's nothing wrong with using non-portable methods. Even fflush(stdin) (which is otherwise undefined) is fine on compilers that support it. But it could be the case that you're simply approaching the problem in the wrong way, which is why I want to know what you're trying to accomplish at a higher level. If we know that then there might be a portable solution that's sufficient.

ok. let's see ) =

Imagine that we have a very simple console menu function <strong>"mainmenu()"</strong> - something like this =

int mainmenu(void)
  {
     int ch; 
	 char* mtext = " Please specify the number of the task. \n * You can choose on number from set = {1} \n * Specify \"0\" to exit\n" ;
	 char* errmes = " Error(!) = Main menu does not support this command.\n Make sure that your task number is from menu set of commands and try again. " ;
	 
	while (getchar() != '\n'); /*here we are cleaning the input = fflush(stdin) isn't cool variant;or use while (getchar() != '\n'); - but this'll stop program*/
       printf("\n%s",mtext );
      ch = getchar() ; /*user choose an item*/
	
	 switch(ch)
     {
		case '0':    printf("\n%s","you choise is item1 \n" );   /*menu item = just put here the name of your function instead of  printf()*/
		                break;
		case '1':    printf("\n%s","you choise is item2 \n" );   /*menu item =  here the name of your function instead of  printf()*/
			         break;
		default: printf("\n%s\n", errmes);
	 }	
   return 0; 
  }

There are 2 situations of mainmenu() work =
1) We get the first when the stdin wasn't empty at the moment we call this function =

int main()
	 { 
                char ch;
                printf("\n%s","please specify a one symbol" ); /* but user've put "dgfhj3  \n"  */
                ch = getchar();
   /*in buffer we have "gfhj3  \n"*/
		 mainmenu();
	return 0;
	 }

And in this situation all will we ok, because line

while (getchar() != '\n');

will remove all data from stdin.

2) But may be the second variant - when the stdin is clear (empty) =

int main()
	 { 
   /*in buffer we have nothing*/
		 mainmenu();
	return 0;
	 }

In this situation the line

while (getchar() != '\n');

will stop the program waiting from user at least an Enter pressing - but this isn't good - least because we even don't know- should we put a prompt message like this =

printf("\n%s"," technical pause - press Enter please" );

or not.
So as I think (and need) sould be a way to avoid this stopping.

It's not the callee's job to clean up after the caller. I think that mainmenu() should simply expect the stream to be in a usable state, and if the caller fails to meet that expectation, it will need to handle erroneous processing by mainmenu().

in terms of programming philosophy you're really right.....i even haven't thought about it....but still - is there any good(with standard behaviour in different compilers and platforms) way to do this?

So as I think (and need) sould be a way to avoid this stopping.

These functions are designed to be used with '\n'

If you don't like the function, don't use it. Design your own.

hkdani you isn't right - it's design for using with ONE \n - and then only after user've specify the value

is there any good(with standard behaviour in different compilers and platforms) way to do this?

No. If you want to do it, you'll need to use a non-portable method for each target environment.

getchar() by definition operates on a character.

A character is defined as one of the input results you find defined on the ASCII chart.

'\n' is a character on the ASCII chart. You can use '\n' with getchar()

hi there)
guys , please tell me - is there any way to check that the standart input is empty or no.
big thanks in advance)

Just assume that the getchar() function has prepared stdin for use. Mainly, because it has.

Your job is to deal with the results of getchar(). If you feel uneasy about the state of stdin before calling getchar(), then use a debugger to step into the assembly code language to verify that it has done the job it was programmed to do.

But the answer to your question is yes.

ok! so if we use construction

#ifdef 
#if defined(_WIN32) || defined (_WIN64) 
#include <windows.h>
	#define  IN_WINDOWS 1
#endif

     #ifdef  IN_WINDOWS
       // code	
     #else
       // code
     #endif

we check stdin for both of windows and linux? how to do this?)
or where can i read about it?) tell please)

Use fgets() . It clears the buffer and places the data into a char* of your choice. There's the input buffer you have total control over.

commented: +++++ +3

fgets() also stop program if the buffer is clear)

Let's recap:

hi there)
guys , please tell me - is there any way to check that the standart input is empty or no.
big thanks in advance)

There's no portable way to do this without actually blocking for input.

in terms of programming philosophy you're really right.....i even haven't thought about it....but still - is there any good(with standard behaviour in different compilers and platforms) way to do this?

ok! so if we use construction

#ifdef 
#if defined(_WIN32) || defined (_WIN64) 
#include <windows.h>
	#define  IN_WINDOWS 1
#endif

     #ifdef  IN_WINDOWS
       // code	
     #else
       // code
     #endif

we check stdin for both of windows and linux? how to do this?)
or where can i read about it?) tell please)

No. If you want to do it, you'll need to use a non-portable method for each target environment.

Are you getting the message at all?

yea but you left out this =

ok. let's see ) =

Imagine that we have a very simple console menu function <strong>"mainmenu()"</strong> - something like this =

int mainmenu(void)
  {
     int ch; 
	 char* mtext = " Please specify the number of the task. \n * You can choose on number from set = {1} \n * Specify \"0\" to exit\n" ;
	 char* errmes = " Error(!) = Main menu does not support this command.\n Make sure that your task number is from menu set of commands and try again. " ;
	 
	while (getchar() != '\n'); /*here we are cleaning the input = fflush(stdin) isn't cool variant;or use while (getchar() != '\n'); - but this'll stop program*/
       printf("\n%s",mtext );
      ch = getchar() ; /*user choose an item*/
	
	 switch(ch)
     {
		case '0':    printf("\n%s","you choise is item1 \n" );   /*menu item = just put here the name of your function instead of  printf()*/
		                break;
		case '1':    printf("\n%s","you choise is item2 \n" );   /*menu item =  here the name of your function instead of  printf()*/
			         break;
		default: printf("\n%s\n", errmes);
	 }	
   return 0; 
  }

There are 2 situations of mainmenu() work =
1) We get the first when the stdin wasn't empty at the moment we call this function =

int main()
	 { 
                char ch;
                printf("\n%s","please specify a one symbol" ); /* but user've put "dgfhj3  \n"  */
                ch = getchar();
   /*in buffer we have "gfhj3  \n"*/
		 mainmenu();
	return 0;
	 }

And in this situation all will we ok, because line

while (getchar() != '\n');

will remove all data from stdin.

2) But may be the second variant - when the stdin is clear (empty) =

int main()
	 { 
   /*in buffer we have nothing*/
		 mainmenu();
	return 0;
	 }

In this situation the line

while (getchar() != '\n');

will stop the program waiting from user at least an Enter pressing - but this isn't good - least because we even don't know- should we put a prompt message like this =

printf("\n%s"," technical pause - press Enter please" );

or not.
So as I think (and need) sould be a way to avoid this stopping.

yea but you left out this =

And you found a way to do it then. Please post your solution so we all can learn from it...

And you found a way to do it then. Please post your solution so we all can learn from it...

i'm not so clever to understand you ) as you can understand from previous messages - i don't know the solution)

I was playing with the code provided by 'hkdani' and the mere idea that 'stdin' uses a char pointer '_ptr' to point to the data in the buffer, I tried to compile the following code(just for fun, cause it's been itching me):

#include <stdio.h>
#include <string.h>
int main(void)
{
    FILE *pFile ;
    int i;
	char name[5];

    pFile = stdin ;
    i = strlen (pFile->_ptr) ;//_ptr is char buffer in struct _iobuf
    printf("%d bytes in stdin\n",i) ;
	printf("enter your name\n");
    scanf("%5[1234]",&name);

   while((i = strlen (pFile->_ptr))>=1){
	   printf("%d bytes in stdin\n",i) ;
	   if(i==1)//atleast 1 character needed for getchar
		   break;
	   printf("removing \'%c\' from the buffer\n",getchar());

	}


    return 0 ;
}

first shows

0 bytes in stdin
enter your name

input:

rakawid

after pressing enter shows:

9 bytes in stdin
removing 'r' from the buffer
8 bytes in stdin
removing 'a' from the buffer
7 bytes in stdin
removing 'k' from the buffer
6 bytes in stdin
removing 'a' from the buffer
5 bytes in stdin
removing 'w' from the buffer
4 bytes in stdin
removing 'i' from the buffer
3 bytes in stdin
removing 'd' from the buffer
2 bytes in stdin
removing '
' from the buffer
1 bytes in stdin

"9 bytes in stdin", what's that extra byte? does anyone know?

commented: +++ +3
commented: A willing and inquisitive mind that probes the depths to add knowledge. Gems of wisdom will be gleaned from this source. +6

what's that extra byte? does anyone know?

Perhaps a sentinel, or some kind of bookkeeping data. It might even be part of the CRLF combination if you're on Windows and the implementation uses a move-to-rear strategy of removal.

Ultimately, the problem is that you're using implementation internals without understanding how they work. In my experience, a more reliable method for this kind of hack is with the _cnt member (or equivalent):

#include <stdio.h>

int main(void)
{
    int ch;
    
    printf("Type something: ");
    fflush(stdout);
    
    ch = getchar();
    
    if (ch != EOF)
        printf("First: '%c' -- %d\n", ch, ch);
    
    while (stdin->_cnt != 0) {
        ch = getchar();
        printf("Remaining: '%c' -- %d\n", ch, ch);
    }
    
    return 0;
}

That member is typically used internally for the same purpose, which means you can use it with relative confidence, unlike strlen(stdin->_ptr) .

commented: thanks! +4

"9 bytes in stdin", what's that extra byte? does anyone know?

The debugger knows. All you have to do is ask. Just put a stop at the appropriate line in you code, preferably before the values inside stdin go out of scope.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.