473,668 Members | 2,690 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

fgets behaviour with strncmp

Hi all,

Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:

prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.

I've thrown a few random fflush()'s in, but no joy. I have never
really learnt the ANSI way ala fgets, fopen, etc.. so this is quite
new to me. Any advice on how I can actually make the program quit
when "quit" is entered would be appreciated :-)

Code:

#include <stdio.h>

int main()
{

int done=0;
int len=0;
char buf[MAXBUF];

printf("");
while(!done)
{
if(fgets(buf,MA XBUF,stdin) < 0)
{
perror("fgets") ;
exit(1);
}

len=strlen(buf) ;
buf[len]='\0';

fflush(stdin);
if(*buf == '\n')
printf("");
printf("debug: %s\n",buf);
fflush(stdin);
fflush(stdout);
if(!strncmp(buf ,"quit",len) )
done=1;
}
return 0;
}

thanks

kb
Jun 27 '08 #1
12 1851
On Jun 17, 11:01 am, Krumble Bunk <krumbleb...@gm ail.comwrote:
Hi all,

Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:

prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.

I've thrown a few random fflush()'s in, but no joy. I have never
really learnt the ANSI way ala fgets, fopen, etc.. so this is quite
new to me. Any advice on how I can actually make the program quit
when "quit" is entered would be appreciated :-)

Code:

#include <stdio.h>

int main()
{

int done=0;
int len=0;
char buf[MAXBUF];

printf("");
while(!done)
{
if(fgets(buf,MA XBUF,stdin) < 0)
{
perror("fgets") ;
exit(1);
}

len=strlen(buf) ;
buf[len]='\0';

fflush(stdin);
if(*buf == '\n')
printf("");
printf("debug: %s\n",buf);
fflush(stdin);
fflush(stdout);
if(!strncmp(buf ,"quit",len) )
done=1;
}
return 0;

}

thanks

kb
Lots of issues there, but your central problem is that buf includes
the newline. If you set (after appropriate checking) buf[len-1] to
'\0' and use strcmp you will fix that. A few other points:

don't fflush(stdin)
do include string.h, stdlib.h
do define MAXBUF somewhere
do turn on your compilers warnings...

-David
Jun 27 '08 #2
On Jun 17, 4:14 pm, David Resnick <lndresn...@gma il.comwrote:
On Jun 17, 11:01 am, Krumble Bunk <krumbleb...@gm ail.comwrote:
Hi all,
Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:
prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.
I've thrown a few random fflush()'s in, but no joy. I have never
really learnt the ANSI way ala fgets, fopen, etc.. so this is quite
new to me. Any advice on how I can actually make the program quit
when "quit" is entered would be appreciated :-)
Code:
#include <stdio.h>
int main()
{
int done=0;
int len=0;
char buf[MAXBUF];
printf("");
while(!done)
{
if(fgets(buf,MA XBUF,stdin) < 0)
{
perror("fgets") ;
exit(1);
}
len=strlen(buf) ;
buf[len]='\0';
fflush(stdin);
if(*buf == '\n')
printf("");
printf("debug: %s\n",buf);
fflush(stdin);
fflush(stdout);
if(!strncmp(buf ,"quit",len) )
done=1;
}
return 0;
}
thanks
kb

Lots of issues there, but your central problem is that buf includes
the newline. If you set (after appropriate checking) buf[len-1] to
'\0' and use strcmp you will fix that. A few other points:

don't fflush(stdin)
do include string.h, stdlib.h
do define MAXBUF somewhere
do turn on your compilers warnings...

-David
many thanks - fixed it nicely.

thanks again

kb.
Jun 27 '08 #3
Krumble Bunk wrote, On 17/06/08 16:01:

<snip>

In addition to the other comment you have seen...

Random changes to code (you mentioned throwing in random calls to
fflush) is NEVER a good way to develop.
#include <stdio.h>

int main()
Better would be
int main(void)
{

int done=0;
int len=0;
char buf[MAXBUF];

printf("");
In this instance a do-while loop makes more sense since you always want
to run the loop at least once.
while(!done)
{
fflush(stdout);

With your code the first prompt might not be displayed before waiting
for input.
if(fgets(buf,MA XBUF,stdin) < 0)
{
perror("fgets") ;
exit(1);
This is not a portable value to pass to exit. Only 0, EXIT_SUCCESS and
EXIT_FAILURE are portable. Some times there are good reasons to use
non-portable return codes, but not here.

Also, later you use a return rather than calling exit. You should be
consistent in which method you use to leave main. Personally I normally
use return.
}

len=strlen(buf) ;
buf[len]='\0';
This would not do what you want if too long a line was input. Check to
see if it was a newline first.
fflush(stdin);
fflush is not defined for input streams by the C standard. Some
implementations *might* define it, but others definitely don't.
if(*buf == '\n')
printf("");
Better in my opinion to be consistent about whether you are using array
or pointer operators on buf. Mind you, printing the prompt here seems
odd and doing so conditionally seems even more odd.
printf("debug: %s\n",buf);
fflush(stdin);
fflush(stdout);
if(!strncmp(buf ,"quit",len) )
done=1;
After switching to a do-while loop you could put the above test as the
condition and scrap the done flag!
}
return 0;
}
--
Flash Gordon
Jun 27 '08 #4
Krumble Bunk wrote:
Hi all,

Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:

prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.
<snip>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_LINE 128

int main(void)
{
char buf[MAX_LINE], *line = buf;
int done = 0;

do {
fprintf(stdout, "");
fflush(stdout);
if (fgets(buf, sizeof buf/sizeof buf[0], stdin) == NULL) {
fprintf(stderr, "Input error.\n");
exit(EXIT_FAILU RE);
}
/* skip leading whitespace */
while (isblank((int)* line)) line++;
if (strcmp(line, "quit\n") == 0 || strcmp(line, "quit") == 0) {
done = 1;
}
line = buf;
} while (!done);
return 0;
}

Jun 27 '08 #5
santosh <sa*********@gm ail.comwrites:
Krumble Bunk wrote:
>Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:

prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.

<snip>

#include <ctype.h>

int main(void)
{
<snip>
while (isblank((int)* line)) line++;
Presumably you intended to write isblank((unsign ed char)*line) here.
I can't see any value in the cast to int.

<snip>
}
--
Ben.
Jun 27 '08 #6
Ben Bacarisse wrote:
santosh <sa*********@gm ail.comwrites:
>Krumble Bunk wrote:
>>Having some trouble with a seemingly-simple task. Need to have a
basic CLI functionality as per:

prompt <- \n
prompt <- \n
promptquit <- should quit as per my snippet, but doesn't.

<snip>

#include <ctype.h>

int main(void)
{
<snip>
> while (isblank((int)* line)) line++;

Presumably you intended to write isblank((unsign ed char)*line) here.
I can't see any value in the cast to int.
You are right. In fact, would the cast to unsigned char be necessary at
all, given that all the characters returned by fgets are guaranteed to
be positive integers?

<snip>

Jun 27 '08 #7
santosh said:

<snip>
In fact, would the cast to unsigned char be necessary at
all, given that all the characters returned by fgets are guaranteed to
be positive integers?
Chapter and verse, please. I think you're mistaken about the existence of
such a guarantee. It applies to fgetc, yes, but not to fgets.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #8
Richard Heathfield wrote:
santosh said:

<snip>
>In fact, would the cast to unsigned char be necessary at
all, given that all the characters returned by fgets are guaranteed
to be positive integers?

Chapter and verse, please. I think you're mistaken about the existence
of such a guarantee. It applies to fgetc, yes, but not to fgets.
Aren't all the standard byte input functions implemented as if they were
composed of successive calls to fgetc? If so, a guarantee for fgetc
should be applicable to functions modelled upon it too.

Jun 27 '08 #9
santosh said:
Richard Heathfield wrote:
>santosh said:

<snip>
>>In fact, would the cast to unsigned char be necessary at
all, given that all the characters returned by fgets are guaranteed
to be positive integers?

Chapter and verse, please. I think you're mistaken about the existence
of such a guarantee. It applies to fgetc, yes, but not to fgets.

Aren't all the standard byte input functions implemented as if they were
composed of successive calls to fgetc?
Yes.
If so, a guarantee for fgetc
should be applicable to functions modelled upon it too.
And so it is - for just as long as you are storing the results in an array
of unsigned char. But you're not, are you? You're storing them (quite
properly) in an array of char. So, on systems where char is signed by
default (and there are still quite a few of those about), you have a
problem if you assume that they are representable as unsigned char without
a conversion taking place. For example, consider an input to fgets that
includes a character with code point 130, on a system with 8-bit char,
signed by default. The fgets function will read this as if via fgetc, so
the value 130 will be returned from fgetc (or "as-if-fgetc" if you prefer)
as an int. This fulfils the terms of the contract that you mentioned. Now
fgets has to store this value somewhere in your array of char. Since, on
the system I've mentioned, CHAR_MAX is 127, fgets will have to store the
130 into that array as a negative number: -126 is a definite possibility
(I know because it's what happens on my system!), and -126 is not
representable as unsigned char, because unsigned char can't represent
negative values unless they are first converted into non-negative values.

In the case in point, the C99 function isblank is being used. This is one
of the "is*" functions, prototyped in <ctype.h>, that require their input
to be either EOF or a value representable as an unsigned char. We have
discussed many times before how negative values can foul this up. For
example:

#define isblank(x) ( ((x) == EOF) ? (x) : __isblank[(x)] )

which invokes undefined behaviour if passed a negative value other than
EOF. (E&OE - my track record on illustrative is* macros is appalling.)

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

26
12994
by: pembed2003 | last post by:
Hi, I have an application where I use the strncmp function extensively to compare 2 string to see if they are the same or not. Does anyone know a faster replacement for strncmp? I notice there is a memncmp function which is very fast but it doesn't work the same like strncmp so I don't think I can use it. I also tried to write the string_equal function myself like: int string_equal(const char* s1,const char* s2){ while(*s1 && *s2 &&...
7
1766
by: William L. Bahn | last post by:
I recently challenged one of my students to figure out a way to determine if fgets() actually received the entire contents of the input string. When he was having trouble figuring it out even after I recommended he look carefully at the difference between the two cases when the input was short enough and when the input was too long, I suggested he look at the FAQ for this newsgroup. He came back and said he couldn't find anything, so I went...
26
3259
by: Peter Mount | last post by:
Hello What's the syntax for using fgets() to store a string in memory? I understand that fgets() can solve the problem of storing a string that has more characters than the size of the declared array. Thanks Peter Mount info@petermount.au.com
20
7891
by: TTroy | last post by:
Hello, I have found some peculiar behaviour in the fgets runtime library function for my compiler/OS/platform (Dev C++/XP/P4) - making a C console program (which runs in a CMD.exe shell). The standard says about fgets: synopsis #include <stdio.h> char *fgets(char *s, int n, FILE *stream);
11
3657
by: santosh | last post by:
Hi, A book that I'm currently using notes that the fgets() function does not return until Return is pressed or an EOF or other error is encountered. It then at most (in the absence of EOF/error), returns n-1 characters plus a appended null character.
32
3873
by: FireHead | last post by:
Hello C World & Fanatics I am trying replace fgets and provide a equavivalant function of BufferedInputReader::readLine. I am calling this readLine function as get_Stream. In the line 4 where default_buffer_length is changed from 4 --24 code works fine. But on the same line if I change the value of default_buffer_length from 4 --10 and I get a memory error. And if the change the value of the same variable from 4 --1024 bytes;
285
8801
by: Sheth Raxit | last post by:
Machine 1 : bash-3.00$ uname -a SunOS <hostname5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R bash-3.00$ gcc -v Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/ specs gcc version 2.95.3 20010315 (release)
6
3368
by: Gert Kok | last post by:
When fgets() reads a string that ands with <<<EOT, the string is truncated after << and a lot of following input is discarded. When <<<EOT is changed to <<< EOT, behaviour is as I expect it. Can it be explained why the content of a file is interfering with the behaviour of fgets()?
0
8797
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8583
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8656
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7401
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6209
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4205
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4380
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2791
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2023
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.