LinuxQuestions.org
Review your favorite Linux distribution.
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 01-15-2014, 01:05 PM   #16
arashi256
Member
 
Registered: Jan 2008
Location: Brighton, UK
Distribution: Ubuntu 18.04 / CentOS 7.6
Posts: 397

Original Poster
Rep: Reputation: 62

As per my last post and reading the new posts here, I don't think I quite understand stdin then. I don't get why the new code works (posted above) or why there is a while loop to get to the end of the stream when the return value of the function has already been set a line before. But if I take that part out, the code breaks.

It seems to me that if I type 'SPACE' then 'BACKSPACE' then 'y' the contents of the char array should be: -

0: y
1: \n

...yet from the talk here, it seems as though the char array will have something like: -

0: SPACE
1: BACKSPACE
2: y
3: \n

I also don't understand this part which may be related to the above.

Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
return ret;
I'm assuming this line: -

Code:
ret = ch == 'y';
is shorthand for something like: -

Code:
if (ch == 'y') {
    ret = 1;
} else {
    ret = 0;
}
The while loop that assigns the current value of ch is run after the return value has been set. And all it's doing is rolling through the char array until it gets to \n (EOF) and assigning the last character to ch. But the value of ret never changes yet if I take this while loop out, the program breaks.

I appear to be missing some vital piece of information that my book (Head First C) hasn't covered yet.
 
Old 01-15-2014, 01:10 PM   #17
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
I'm definitely on board with the note that my original offering of using fflush() was incorrect. Weird that you used exactly that, because you experimented and found it to work.

My suspicion is that it really didn't work and the results were due to the length of what you grabbed, the length of data coming in from stdin, and the behavior of fgets().

The complete thing here would be to use gdb on a program, break after the fgets() call and see what's in the array.

I see no reason to use an array of only 2 characters. What's the point of that? Use something larger.

I just took the proposed solution by metashima and modified it to have an array of 32 characters versus 3. I also changed the fgets call to use sizeof(str) versus "32", my personal protective coding preference. Compiled that with GDB flags, set a breakpoint for the sscanf() line, then ran; typed in "abcdef\b\b\bghi" In dumping the memory of that array, I found it to contain:

{ 'a', 'b', 'c', 'g', 'h', 'i', 0x10, 0x00, followed by uninitialized junk }

That got me to thinking about overflow and an earlier comment to check the result of fgets().

Turns out fgets() returns a pointer to the string or NULL indicating error. In checking for this error, I would print out errno if the pointer was NULL; otherwise, proceed to the sscanf().

I typed in the small letter alphabet, followed by 0123456789, which is 26 letters followed by 10 digits, for a total of 36 total characters, adding newline and NULL it would then be 38.

fgets() accepted this and returned a valid pointer which was the address of the str array. The byte contents of str contained the entire alphabet, plus 0, 1, 2, 3, 4, followed by NULL. Twenty six letters, plus 5 digits comes to 31; the 32nd array location was made to be NULL. I dumped out memory beyond the str array and it was no overwritten.

Reading the manpage from fgets() this is exactly what it should do:

"char *fgets(char *s, int size, FILE *stream);"

"fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer."

I then further modified to make it return always zero so that it would go back and parse some more. The first result of the fgets() was as above, 26 letters, 5 digits, NULL in the 32nd array location.

Since stdin still contained information, I did not have to type anything in, and the fgets() returned the 5 remaining digits, the NEWLINE, and NULL.

My final thought on the matter was whether or not someone could ascertain the length of stdin so as to grab the required amount. That's not possible though, because stdin is a pipe and there's nothing in it until you request to read data from it; hence fgets().

My conclusion is protective programming where you ensure that you've seen all you need to see and don't make assumptions that the operator always typed exactly what you expected them too.

Salient points are that the backspace eradicates characters, at least with my shell. I've been in shells, mostly remote shell attachments; where backspace shows on the screen, that's either character translation for the display, or not. I do believe it is display only because I've had cases of a typo, I backspace, it gets ugly, but I fix it properly and the end result works.

Last edited by rtmistler; 01-15-2014 at 01:11 PM.
 
1 members found this post helpful.
Old 01-15-2014, 01:25 PM   #18
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by arashi256 View Post
I appear to be missing some vital piece of information that my book (Head First C) hasn't covered yet.
Recommendations here are:
  1. Check the manpages for library and system calls - understand the return conditions, errno, and so forth
  2. Try using GDB, breakpoints, disable optimization, assign and print out returns or information to variables to be able to inspect things in the debugger

Some suggested things to do:

Code:
- Make a test.c file, like you have.
- Declare a local variable "char *ret" to be the return from fgets().
- Test that value.
- Print that value.  If the return fails (NULL in this case) print out errno; include <errno.h>
- Compilation command would be something like: gcc test.c -o test -ggdb
  - gcc - compile, you probably know
  - -o directs the output to be test versus "a.out"
  - -ggdb - should enable GDB debugging, although I think it may be available anyways.
- Run the program using: gdb test, you'll get a gdb prompt.
- Set breakpoints like: b test.c:32 - sets breakpoint in test.c at line 32; it should be a code line; otherwise it may set the breakpoint at the next code line it feels is appropriate.
- You can set more than one breakpoint.
- Type run, to run it.  Note if you have arguments for your program you can set them either entering GDB or at the GDB prompt, read up on GDB for advanced stuff.
- Once you hit a breakpoint, you can do stuff like "print" or "examine" variables and memory:
p str - prints the variable str; it will print the legal string that str has.
x/32b str - examines the array str, byte by byte and prints out the decimal value of each array entry, there's a way to change it to show you hex, here's an online ASCII table which shows hex, ascii, octal, decimal; I find that more helpful than constantly relearning something I always forget to do in gdb. Ascii Table.

Other GDB commands:
s - single step
c - continue either to end, or if it hits a breakpoint, or runs forever because there's a loop (CTRL-C will get you out)
quit - quit GDB, it may complain that you have a process running, you intend to quit, so do so.
 
1 members found this post helpful.
Old 01-15-2014, 01:42 PM   #19
arashi256
Member
 
Registered: Jan 2008
Location: Brighton, UK
Distribution: Ubuntu 18.04 / CentOS 7.6
Posts: 397

Original Poster
Rep: Reputation: 62
Thanks for the gdb info....not used it yet!
On this: -

Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
return ret;
...I'd expect the line which assigns the value of 'ret' to be below the while loop which gets the last valid character before either \n or \0 is hit. Yet if I move the line 'ret = ch == 'y';' to be below the while loop like I'd expect, the program breaks. But the value of 'ret' has already been assigned based on the current character returned from the first call to getchar().
Confused.

Last edited by arashi256; 01-15-2014 at 01:43 PM.
 
Old 01-15-2014, 01:56 PM   #20
metaschima
Senior Member
 
Registered: Dec 2013
Distribution: Slackware
Posts: 1,982

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
I'm not sure why my solution is ignored, even tho doesn't involve flushing.

You have to remember that keyboard input is buffered, usually line buffered. So, characters are not immediately available to your program as you would expect with no buffering. You're pulling them from the buffer and if something is left in the buffer, you have to flush it out. Really, you can avoid such issues by simply matching the buffer, i.e. using fgets, which stops at a new line = line buffered, but making sure to get the newline. The scanf group of functions are very bad at handling line-buffering, they leave newlines and other invisible characters in the buffer and the messes up input after that if you don't flush. So, basically, you can use fgets or you can use scanf + flush. I say the former is far more elegant.

Also remember that a C string is NULL terminated, which you do not seem to include in your examples.

It is:
y
\n
\0

that would be stored in the string. If your string is only 2 characters long, then you will store:
y
\0

and leave in the buffer:
\n

Last edited by metaschima; 01-15-2014 at 01:58 PM.
 
Old 01-15-2014, 02:00 PM   #21
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by metaschima View Post
I'm not sure why my solution is ignored, even tho doesn't involve flushing.

You have to remember that keyboard input is buffered, usually line buffered. So, characters are not immediately available to your program as you would expect with no buffering. You're pulling them from the buffer and if something is left in the buffer, you have to flush it out. Really, you can avoid such issues by simply matching the buffer, i.e. using fgets, which stops at a new line = line buffered, but making sure to get the newline. The scanf group of functions are very bad at handling line-buffering, they leave newlines and other invisible characters in the buffer and the messes up input after that if you don't flush. So, basically, you can use fgets or you can use scanf + flush. I say the former is far more elegant.
When I did all that studying of cases I blabbed about, I had used your solution and modified from there. I did start by compiling it as is and testing it.
 
Old 01-15-2014, 04:06 PM   #22
Spect73
Member
 
Registered: Aug 2013
Distribution: Slackware 14.1
Posts: 128

Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
I'm definitely on board with the note that my original offering of using fflush() was incorrect. Weird that you used exactly that, because you experimented and found it to work.
No sir. You misread my post. I said it DID NOT WORK. And, I was surprised. Reading the man page could lead one to believe that it would. Had it worked, it wouldn't matter what was left in the stdin buffer, the call would have flushed it out. Since it didn't work, the remainder of the data was left in the stdin buffer, and was obtained via the subsequent calls to fgets.

As to this statement:
Quote:
Originally Posted by rtmistler View Post
My final thought on the matter was whether or not someone could ascertain the length of stdin so as to grab the required amount. That's not possible though, because stdin is a pipe and there's nothing in it until you request to read data from it; hence fgets().
Actually it is possible to get the length of stdin. The following, somewhat lengthy code is (mostly) from pages 154 and 155 of Advanced Programming in the UNIX Environment 2nd edition. It points out that the code is non portable, and it uses GNU libc structure members and constants. When I run this, I get a value of 1024 bytes for stdin, 1024 bytes for stdout, 1 byte for stderr, while 'normal' file input is 4096 bytes. And, if I follow the books example and redirect stdin & stdout, I find that stdin/stdout both go to 4096 bytes.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>

#define	ERRORLINELEN	1024

void pr_stdio(const char *name, FILE *fp);
static void	err_doit(int, int, const char *, va_list);
void sys_err(const char *fmt, ...);

/*   NOTE: we perform I/O on each stream before printing its buffering
     status, since the first I/O operation usually causes the buffers to
     be allocated for a stream.  The structure members:
        _IO_file_flags
        _IO_buf_base
        _IO_buf_end
     and the constants:
        _IO_UNBUFFERED
        _IO_LINE_BUF
     are defined by the GNU standard I/O library used on Linux.  Be aware
     that other UNIX systems may have different implementations of the
     standard I/O library.
*/
int main(int argc, char **argv) {
	FILE *fp;

	fputs("enter any character",stdout);
	if(getchar() == EOF)
		sys_err("getchar error");
	else
		putc('\n',stdout);
	fputs("one line to standard error\n",stderr);

	pr_stdio("stdin",stdin);
	pr_stdio("stdout",stdout);
	pr_stdio("stderr",stderr);

	fp = fopen("/etc/motd","r");
	if(!fp)
		sys_err("fopen error on /etc/motd");
	if(getc(fp) == EOF)
		sys_err("getc error");
	pr_stdio("/etc/motd",fp);
	exit(0);
}

void pr_stdio(const char *name, FILE *fp) {
	printf("stream = %s, ",name);

	/*	The following is nonportable */
	if(fp->_IO_file_flags & _IO_UNBUFFERED)
		printf("unbuffered");
	else if(fp->_IO_file_flags & _IO_LINE_BUF)
		printf("line buffered");
	else
		printf("fully buffered");
	printf(", buffer size = %d\n",fp->_IO_buf_end - fp->_IO_buf_base);
}

/*	sys_err: error related to a system call that needs to terminate
	processing.  Print a message and exit.
*/
void sys_err(const char *fmt, ...) {
	va_list		ap;

	va_start(ap, fmt);
	err_doit(1, errno, fmt, ap);
	va_end(ap);
	exit(1);
}

/*	err_doit: print a message and return to caller.
	Caller specifies "errnoflag".
*/
static void err_doit(int errnoflag,int error,const char *fmt, va_list ap) {
	char	buf[ERRORLINELEN];

	vsnprintf(buf, ERRORLINELEN, fmt, ap);
	if (errnoflag)
		snprintf(buf+strlen(buf),ERRORLINELEN-strlen(buf),": %s",strerror(error));
	strcat(buf, "\n");
	fflush(stdout);		/* in case stdout and stderr are the same */
	fputs(buf, stderr);
	fflush(NULL);		/* flushes all stdio output streams */
}
 
1 members found this post helpful.
Old 01-15-2014, 04:23 PM   #23
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,781

Rep: Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082Reputation: 2082
Quote:
Originally Posted by arashi256 View Post
Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
return ret;
...I'd expect the line which assigns the value of 'ret' to be below the while loop which gets the last valid character before either \n or \0 is hit. Yet if I move the line 'ret = ch == 'y';' to be below the while loop like I'd expect, the program breaks. But the value of 'ret' has already been assigned based on the current character returned from the first call to getchar().
If you move that down, you're basing the return value on the last character, which is always '\n' (or EOF, not really a character). If you want ret at the end you could do this:
Code:
// read and save the first character
int first_char = getchar();
// read and ignore the rest 
while (1) {
    int ch = getchar();
    if (ch == EOF || ch == '\n') break;
}
ret = (first_char == 'y');
return ret;
Quote:
Originally Posted by Spect73
Reading the man page could lead one to believe that it would. Had it worked, it wouldn't matter what was left in the stdin buffer, the call would have flushed it out. Since it didn't work, the remainder of the data was left in the stdin buffer, and was obtained via the subsequent calls to fgets.
fflush() affects libc's buffers, the terminal has its own buffer to implement line editing (backspace etc).
 
Old 01-15-2014, 04:51 PM   #24
Spect73
Member
 
Registered: Aug 2013
Distribution: Slackware 14.1
Posts: 128

Rep: Reputation: Disabled
Quote:
Originally Posted by arashi256 View Post
As per my last post and reading the new posts here, I don't think I quite understand stdin then. I don't get why the new code works (posted above) or why there is a while loop to get to the end of the stream when the return value of the function has already been set a line before. But if I take that part out, the code breaks.

It seems to me that if I type 'SPACE' then 'BACKSPACE' then 'y' the contents of the char array should be: -

0: y
1: \n

...yet from the talk here, it seems as though the char array will have something like: -

0: SPACE
1: BACKSPACE
2: y
3: \n
@arashi256
In your code, you had set a buffer 'input' to a length of 2. fgets will read a maximum of one less bytes than you tell it to. So, when you gave a call of
Code:
fgets(input, 2, stdin);
you were telling fgets to read a single byte, and you ended up with the following in your 'input' buffer:
0: y
1: '\0'
However, the stdin buffer, which is maintained by the standard I/O library buffers much more data that what you were reading in. So, it still had the '\n' character in it. Your next call then fetched this character and caused your loop to not work.


Quote:
I also don't understand this part which may be related to the above.

Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
return ret;
I'm assuming this line: -

Code:
ret = ch == 'y';
is shorthand for something like: -

Code:
if (ch == 'y') {
    ret = 1;
} else {
    ret = 0;
}
Yes, you can consider that line to be equivalent to your if/else statement. I admit, I've never seen that construct before. Learn something new everyday. What the while loop is doing is merely consuming the remaining data in the stdin buffer. This will in effect clear out the stdin buffer so that subsequent calls will get what you next type in, not something that was leftover. There is only one problem left with the example supplied above: it returns 1 for 'y' and 0 for 'n'. In your original do/while loop, you were using a return value of 0 for 'y' and '1' for 'n'. These can easily be corrected by doing either:
Code:
ret = ch == 'n';
in @mina86s' code or changing your do/while to:
Code:
} while (loop_input == 1);
 
Old 01-16-2014, 07:59 AM   #25
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by arashi256 View Post
@mina86: -

I don't get this part, though.

Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
Why are you continuing to call getchar() when the ret value has already been set?
You need to consume the whole line otherwise the next time you invoke the function it will read what was not read. This is why you have experienced the problem in the first place.

Here how things work:
- User presses “y” and then Return.
- Kernel puts “y\n” into the file descriptor.
- Standard library reads “y\n” to it's buffer.
- getchar() returns 'y' and advances pointer in the buffer so that it contains "\n".
- Next time you call getchar() it just reads '\n'.

Quote:
Originally Posted by rtmistler View Post
The other thing to consider is bad typists. Someone who types 'b', or 'e', or their password and then backspaces that away and finally answers 'y' or 'n'. All that stuff will be sitting in stdin until it gets taken via fgets().
This is not true unless you switch your terminal to raw mode. Normally standard input is line-buffered and the terminal takes care of handling backspace character, so if someone presses “i”, backspace, “y” and then Return, the application will just receive “y\n”.

metaschima, why are you invoking sscanf exactly if all you need is the first character of the buffer? Besides, your solution won't work if someone presses space after “y”.
 
Old 01-16-2014, 08:17 AM   #26
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by arashi256 View Post
It seems to me that if I type 'SPACE' then 'BACKSPACE' then 'y' the contents of the char array should be: -

0: y
1: \n

...yet from the talk here, it seems as though the char array will have something like: -

0: SPACE
1: BACKSPACE
2: y
3: \n
As I explained, backspace is handled by your terminal so that in the end only "y\n" is sent to standard input of the application.

Quote:
Originally Posted by arashi256 View Post
I'm assuming this line: -
Code:
ret = ch == 'y';
is shorthand for something like: -

Code:
if (ch == 'y') {
    ret = 1;
} else {
    ret = 0;
}
Yes. ch == 'y' is a boolean expression and it's result is stored in ret.

Quote:
Originally Posted by arashi256 View Post
The while loop that assigns the current value of ch is run after the return value has been set. And all it's doing is rolling through the char array until it gets to \n (EOF)
'\n' and EOF are two distinct values!

Quote:
Originally Posted by arashi256 View Post
and assigning the last character to ch. But the value of ret never changes yet if I take this while loop out, the program breaks.
Yes, because you need to read the whole line from standard input, otherwise the next time you'll get garbage from the same line.

Quote:
Originally Posted by rtmistler View Post
That got me to thinking about overflow and an earlier comment to check the result of fgets().
Those are unrelated aspects. One checks return value of fgets to check whether EOF was hit, but strictly speaking this is redundant since you can equally well see whether the first byte of the buffer is '\0' (a NUL byte).

Quote:
Originally Posted by rtmistler View Post
Salient points are that the backspace eradicates characters, at least with my shell. I've been in shells, mostly remote shell attachments; where backspace shows on the screen, that's either character translation for the display, or not. I do believe it is display only because I've had cases of a typo, I backspace, it gets ugly, but I fix it properly and the end result works.
This is not related (or only partially related) to the shell but to the terminal and how it is set up. The same shell can behave differently depending on how exactly you are connecting to the machine.

Quote:
Originally Posted by arashi256 View Post
Thanks for the gdb info....not used it yet!
On this: -

Code:
ch = getchar();
ret = ch == 'y';
while (ch != EOF && ch != '\n') {
    ch = getchar();
}
return ret;
...I'd expect the line which assigns the value of 'ret' to be below the while loop which gets the last valid character before either \n or \0 is hit. Yet if I move the line 'ret = ch == 'y';' to be below the while loop like I'd expect, the program breaks. But the value of 'ret' has already been assigned based on the current character returned from the first call to getchar().
Confused.
If you move the line to the end, ch will always be either EOF or '\n', so never 'y'.

Quote:
Originally Posted by Spect73 View Post
Actually it is possible to get the length of stdin. The following, somewhat lengthy code is (mostly) from pages 154 and 155 of Advanced Programming in the UNIX Environment 2nd edition. It points out that the code is non portable, and it uses GNU libc structure members and constants. When I run this, I get a value of 1024 bytes for stdin, 1024 bytes for stdout, 1 byte for stderr, while 'normal' file input is 4096 bytes. And, if I follow the books example and redirect stdin & stdout, I find that stdin/stdout both go to 4096 bytes.
This gives size of the buffers which is not really that useful information and bares no significance on how long a line read from standard input will be. I can easily create a 10000-character long line and send it down some application's standard input.
 
Old 01-16-2014, 11:37 AM   #27
metaschima
Senior Member
 
Registered: Dec 2013
Distribution: Slackware
Posts: 1,982

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
My concern with the other solution is that it will work if you type in 'yaonetuhasonteidtnhdutnaoi', like if a cat walk across the keyboard.
 
Old 01-16-2014, 03:42 PM   #28
Spect73
Member
 
Registered: Aug 2013
Distribution: Slackware 14.1
Posts: 128

Rep: Reputation: Disabled
Quote:
Originally Posted by mina86 View Post
This gives size of the buffers which is not really that useful information and bares no significance on how long a line read from standard input will be. I can easily create a 10000-character long line and send it down some application's standard input.
It tells me what the maximum amount of bytes that can be returned via a single call of fgets on stdin can return. That is what is significant. As to whether I must make a million calls to finally get to the 'end of the line as specified by a newline' you are correct.
 
Old 01-16-2014, 04:16 PM   #29
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by metaschima View Post
My concern with the other solution is that it will work if you type in 'yaonetuhasonteidtnhdutnaoi', like if a cat walk across the keyboard.
Agreed, that's why a better solution would be to:

0. Print prompt.
1. Read characters until a non-white-space character, a new line character or an EOF is encountered:
2a) If EOF was encountered: return false.
2b) If new line character was encountered: go to step 0.
2c) If 'y' or 'Y' was encountered: set ret to true and go to step 3.
2d) If 'n' or 'N' was encountered: set ret to false and go to step 3.
2e) In any other case go to step 5.
3. Read characters until a non-white-space character, a new line character or an EOF is encountered:
4a) If EOF or new line character was encountered: return ret.
4b) In any other case, go to step 5.
5. Read until new line character or an EOF is encountered:
6a) If new line character was encountered: go to step 0.
6b) If EOF was encountered: return false.

But since the problem OP was facing was related to not reading the whole line as opposed to accepting responses like “yuio”, I didn't want to bring this up. Let's try and solve one problem at a time, and once OP understands what was causing the behaviour he encountered, we can move to other problems.

Quote:
Originally Posted by Spect73 View Post
It tells me what the maximum amount of bytes that can be returned via a single call of fgets on stdin can return.
No, it does not. The size of the buffer you are passing to stdin tells you the maximum amount of bytes a single call to fgets on stdin can return. It has nothing to do with the size of the buffer used by the library to buffer standard input.

Last edited by mina86; 01-17-2014 at 04:55 AM. Reason: Clafiried that size of stdin buffer has nothing to do with what fgets returns.
 
Old 01-16-2014, 10:47 PM   #30
Spect73
Member
 
Registered: Aug 2013
Distribution: Slackware 14.1
Posts: 128

Rep: Reputation: Disabled
Quote:
Originally Posted by mina86 View Post
No, it does not. The size of the buffer you are passing to stdin tells you the maximum amount of bytes a single call to fgets on stdin can return.
Of course you are correct. Since none of this helps the OP, we should quit.
 
  


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 to loop over text file lines within bash script for loop? johnpaulodonnell Linux - Newbie 9 07-28-2015 03:49 PM
Bash script issue (for loop inside a loop) Mperonen Programming 3 08-08-2013 02:14 AM
[SOLVED] Using while loop & select statement - Loop issues Kustom42 Programming 4 05-17-2013 08:43 AM
[SOLVED] Bash - While Loop reading from two lists simultaneously - nested while loop wolverene13 Programming 11 10-01-2011 05:00 PM

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

All times are GMT -5. The time now is 11:07 PM.

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