473,839 Members | 1,503 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Weird problem

Hello everybody,

I was doing one of the exercises in the K&R book, and I got something
really strange. Here's the source code:

/*
* Exercise 2-2 from the K&R book, page 42
*/
#include <stdio.h>

enum loop_control { EXIT, CONTINUE };

int getline (char s[], int lim)
{
short int loop = CONTINUE;
unsigned int i = 0;
int c;

while (loop) {
c = getchar();
if (i == (lim - 2))
loop = EXIT;
else if (c == EOF)
loop = EXIT;
else if (c == '\n')
loop = EXIT;
else
s[i++] = c;
}

if (c == '\n')
s[i++] = c;
s[i] = '\0';

return (i);
}

The strange thing is that lim doesn't seem to control anything at all.
I compiled it using GCC under cygwin on a windows 98 system (I added a
simple main() function that gets a line using getline() and then
prints it).
The strange thing is that even when I put a very small value for lim,
say 10, I can still get very big strings into it without it crashing.
Here's an example output:
$ gcc -o ex exercise2-2.c
$ ./ex
123333333333333 333
123333333333333 3
fdkjghfgsfgkjsd f
fdkjghfgfgkjsdf
(^C)
$

Any feedback will be appreciated!
Cheers!

- Joseph
Nov 13 '05 #1
8 2393


On 11/7/2003 6:31 AM, Jeff wrote:
Hello everybody,

I was doing one of the exercises in the K&R book, and I got something
really strange. Here's the source code: <snip> The strange thing is that lim doesn't seem to control anything at all.
I compiled it using GCC under cygwin on a windows 98 system (I added a
simple main() function that gets a line using getline() and then
prints it).
The strange thing is that even when I put a very small value for lim,
say 10, I can still get very big strings into it without it crashing.
Here's an example output:
$ gcc -o ex exercise2-2.c
$ ./ex
123333333333333 333
123333333333333 3
fdkjghfgsfgkjsd f
fdkjghfgfgkjsdf
Notice that the above string is correct for the first 8 chars (i.e. lim -2 when
lim is 10) then it skips the "s" and keeps going. You didn't by any chance write
your main() function as:

int main() {
...
while(1) {
getline(s,10);
printf("%s",s);
}
...
}

did you? I suspect you're calling getline() in a loop. Show us your "main()" if
that isn't the case.

Ed.
(^C)
$

Any feedback will be appreciated!
Cheers!

- Joseph


Nov 13 '05 #2
ag*******@netco urrier.com (Jeff) wrote:
I was doing one of the exercises in the K&R book, and I got something
really strange. Here's the source code: #include <stdio.h>

enum loop_control { EXIT, CONTINUE };

int getline (char s[], int lim)
{
short int loop = CONTINUE;
unsigned int i = 0;
int c;

while (loop) {
c = getchar();
if (i == (lim - 2))
What if this function is invoked with second parameter < 2 ?

The buffer s isn't used as efficiently as possible, if there's
no '\n' within the first lim-2 characters of input.
loop = EXIT;
else if (c == EOF)
loop = EXIT;
else if (c == '\n')
loop = EXIT;
else
s[i++] = c;
}

if (c == '\n')
s[i++] = c;
s[i] = '\0';

return (i);
You return an unsigned int from a function declared as returning int.
BTW, the parentheses in the return statement are unnecessary.
}

The strange thing is that lim doesn't seem to control anything at all.
I compiled it using GCC under cygwin on a windows 98 system (I added a
simple main() function that gets a line using getline() and then
prints it).
The strange thing is that even when I put a very small value for lim,
say 10, I can still get very big strings into it without it crashing.
Here's an example output:
$ gcc -o ex exercise2-2.c
$ ./ex
123333333333333 333
123333333333333 3
fdkjghfgsfgkjsd f
fdkjghfgfgkjsdf


I cannot reproduce this behaviour. Here's how I used your function:

#define BUFLEN 10

int main( void )
{
char str[BUFLEN];
int n = getline( str, BUFLEN );

printf("%d %s\n", n, str );
return 0;
}

Would you mind to post your main function as well? Maybe something's
wrong with it.

Anyway, how about this:

int getline( char *s, int lim )
{
int i = 0;
int c;

while( ((c = getchar()) != EOF) && (c != '\n') && (i < lim-2) )
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';

return i;
}

Note: this version still uses the buffer provided by the caller
inefficiently, if no '\n' appears within the first lim-2 characters
of input. You may want to improve it (left as an exercise).

Regards
--
Irrwahn
(ir*******@free net.de)
Nov 13 '05 #3
On 7 Nov 2003 04:31:20 -0800
ag*******@netco urrier.com (Jeff) wrote:
Hello everybody,

I was doing one of the exercises in the K&R book, and I got something
really strange. Here's the source code:

/*
* Exercise 2-2 from the K&R book, page 42
*/
#include <stdio.h>

enum loop_control { EXIT, CONTINUE };

int getline (char s[], int lim)
size_t would be better than int, look up size_t in K&R.
{
short int loop = CONTINUE;
I would suggest
enum loop_control loop = CONTINUE;

A good debugger might then show you the enumeration used. If memory was
tight and you wanted to save space then you could make loop a char, but
I can't see any reason for a short in this case.
unsigned int i = 0;
Again, size_t would be a better type.
int c;

while (loop) {
c = getchar();
if (i == (lim - 2))
You have a problem if lim == 1.
loop = EXIT;
else if (c == EOF)
loop = EXIT;
else if (c == '\n')
loop = EXIT;
Why two seperate ifs?
else
s[i++] = c;
}

if (c == '\n')
s[i++] = c;
You could have handled this when you detected the newline above. Also,
if you hit the lim-2 without a newline you have just thrown away a
character.
s[i] = '\0';
A problem if lim==1, even if that is a silly value.

return (i);
}

The strange thing is that lim doesn't seem to control anything at all.
I compiled it using GCC under cygwin on a windows 98 system (I added a
simple main() function that gets a line using getline() and then
prints it).
The strange thing is that even when I put a very small value for lim,
say 10, I can still get very big strings into it without it crashing.
Here's an example output:
$ gcc -o ex exercise2-2.c
$ ./ex
123333333333333 333
123333333333333 3
fdkjghfgsfgkjsd f
fdkjghfgfgkjsdf


If you used the following main you would get a better idea.
#define SIZ 5

int main(void)
{
char buf[SIZ];
int len;
while (1) {
len = getline(buf,SIZ );
printf("\"%s\" %d\n",buf,len);
}
return 0;
}

Here is a possible rework of your code. Note, I've reworked your code
rather than trying to solve the exersize, so it may not be what you
actually want.

int getline (char s[], size_t lim)
{
enum loop_control loop = CONTINUE;
size_t i = 0;
int c;

while (loop) {
c = getchar();
if (c == EOF)
loop = EXIT;
else {
s[i++] = c;
if (c == '\n' || i+1 >= lim)
loop = EXIT;
}
}

if (i<lim)
s[i] = '\0';

return (i);
}

HTH.
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #4
> Anyway, how about this:

int getline( char *s, int lim )
{
int i = 0;
int c;

while( ((c = getchar()) != EOF) && (c != '\n') && (i < lim-2) )
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';

return i;
}


That's the actual function, the exercise is to re-write it without
using &&'s ;)

I can't really remember what my main () function was exactly, but it
was basically something like this:

#define MAXLENGTH 10

int main (void)
{
int len;
char s[MAXLENGTH];

while ((len = getline (s, MAXLENGTH)) > 0)
printf("%s");

return (0);
}

Oh, and BTW I know the parentheses are unecessary, but I just like
writing my code like that.

Thanks for the feedback,

- Joseph
Nov 13 '05 #5
Oups, sorry about the error, it should be printf ("%s", s);

- Joseph
Nov 13 '05 #6


On 11/7/2003 1:06 PM, Jeff wrote:
<snip>
I can't really remember what my main () function was exactly, but it
was basically something like this:

#define MAXLENGTH 10

int main (void)
{
int len;
char s[MAXLENGTH];

while ((len = getline (s, MAXLENGTH)) > 0)
printf("%s");


Change that to:

printf("[%s]",s);

then rerun your test and the source of your problem should become clear.

Ed.

Nov 13 '05 #7
ag*******@netco urrier.com (Jeff) wrote:

[attribution restored, please do not snip it, thank you]
Irrwahn Grausewitz wrote:
Anyway, how about this:

int getline( char *s, int lim )
{
int i = 0;
int c;

while( ((c = getchar()) != EOF) && (c != '\n') && (i < lim-2) )
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';

return i;
}
That's the actual function, the exercise is to re-write it without
using &&'s ;)


Yikes, sorry, I didn't have my copy of K&R handy... :)
I can't really remember what my main () function was exactly, but it
was basically something like this:

#define MAXLENGTH 10

int main (void)
{
int len;
char s[MAXLENGTH];

while ((len = getline (s, MAXLENGTH)) > 0)
printf("%s"); OK, you already corrected this in another reply to read:

printf ("%s", s);

Well, and now consider what happens: you read up to MAXLENGTH-2
characters in the first call of getline, *but* the rest of the
input is still waiting and gets processed in the consecutive calls
to getline. If you change the line to

printf ("%s\n", s);

you'll see that getline works as expected, just your output looked
like it didn't.

return (0);
}

Oh, and BTW I know the parentheses are unecessary, but I just like
writing my code like that.
Well, I just thought I mention it for the sake of whatever... :)
Thanks for the feedback,


You're welcome.

Regards
--
Irrwahn
(ir*******@free net.de)
Nov 13 '05 #8
Jeff <ag*******@netc ourrier.com> wrote:
Hello everybody,
Hello, Jeff,
I was doing one of the exercises in the K&R book, and I got something
really strange. Here's the source code: /*
* Exercise 2-2 from the K&R book, page 42
*/
#include <stdio.h> enum loop_control { EXIT, CONTINUE }; int getline (char s[], int lim)
{
short int loop = CONTINUE;
unsigned int i = 0;
int c; while (loop) {
c = getchar();
if (i == (lim - 2))
loop = EXIT;
else if (c == EOF)
loop = EXIT;
else if (c == '\n')
loop = EXIT;
else
s[i++] = c;
} if (c == '\n')
s[i++] = c;
s[i] = '\0'; return (i);
} The strange thing is that lim doesn't seem to control anything at all.
I compiled it using GCC under cygwin on a windows 98 system (I added a
simple main() function that gets a line using getline() and then
prints it).
Sure it does sometihng.
It leaves room in the buffer for the trailing \n and \0.
That's why you see the expression 'lim - 2'.

The strange thing is that even when I put a very small value for lim,
say 10, I can still get very big strings into it without it crashing.
Here's an example output:
$ gcc -o ex exercise2-2.c
$ ./ex
123333333333333 333
123333333333333 3
fdkjghfgsfgkjsd f
fdkjghfgfgkjsdf
(^C)
$
This seems strange to me, because I ran it under cygwin under
Win2k and I got exactly what I expected.

Here's what I recommend, for your own edification:

Change the four parts of the if-else if-else if-else block to
contain a printf statement that states what's happening.

I did that, too, and here it is:

if (i == (lim - 2))
{
loop = EXIT;
printf ("Hit limit: exiting\n");
}
else if (c == EOF)
{
loop = EXIT;
printf ("Hit EOF: exiting\n");
}
else if (c == '\n')
{
loop = EXIT;
printf ("Hit EOL: exiting\n");
}
else
{
s[i++] = c;
printf ("Adding character '%c'\n", c);
}

I got exactly what I expected.

HTH
Cheers! - Joseph


Nov 13 '05 #9

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

Similar topics

3
2082
by: redneck_kiwi | last post by:
Hi all: I have a really weird problem. I am developing a customer catalog system for my company and as such have delved into sessions for authentication and access levels. So far, I have managed to get a working system just about finished. I am building an interface for our customer service folks to use to manage registered customers and am seeing some weird behavior.
13
3812
by: Wolfgang Kaml | last post by:
Hello All, I have been researching newsgroups and knowledgebase all morning and not found a solution that would solve the problem I have. I am having an ASP or ASPX web page that implement a counter functionality and read/insert some data in a MS Access database on that Windows 2003 server. The weird part is, as long as the web page is very short in size, I can hit the refresh button and Internet Explorer will reload the page and display...
1
2108
by: Kaneda | last post by:
Hello everyone! I have some weird(?) problems, and I am not quite sure if there are due to my errors or maybe a limitation in the .Net framework. I have a ComboBox I need to fill with the content of an untyped DataSet. This is to be done in the "DropDown" Event (since the dataset is empty at program start). If I go with this:
0
1163
by: Kaneda | last post by:
Hello everyone! I have some weird(?) problems, and I am not quite sure if there are due to my errors or maybe a limitation in the .Net framework. I have a ComboBox I need to fill with the content of an untyped DataSet. This is to be done in the "DropDown" Event (since the dataset is empty at program start). If I go with this:
6
1417
by: Unicorn | last post by:
I can only say this is a weird problem! I will be sitting there typing away in the code window, when the whole IDE just vanishes without a trace. I get no error messages and no indication, it is just gone. One second I am typing in the IDE and the next I am in whatever application was behind it on the desktop and my keystroke are going to that active application. There is nothing in the application or security logs to indicate...
1
1535
by: Jeffrey Melloy | last post by:
I recently noticed that in my web app, a \n wasn't getting converted to a <br />. (The problem turned out to be that for this particular record, it was a \r). When I checked out the record in psql, I got some weird behavior. What shows up in the web: amoth4:it is o.o jm:Speaking of being a sounding board, will you test something? jm:Ot
0
1454
by: Zwyatt | last post by:
having a really weird little bug w/ time_t...check it out: I have the following code (simplified here): #include <time.h> class A { public: char *aString; int aNum;
1
1554
by: Strange Cat | last post by:
Hi everyone! I have a weird problem with FormsAuthentication. I have an app that works just fine with FormsAuthentication. The user requests the homepage, he is redirected to login page, then enters valid username and password that are checked versus a db table, if the info is ok i execute SetAuthCookie(xxx, False) then i open a new window which displays the home page, all is working fine...
3
5495
by: aling | last post by:
Execute following T-SQL within Queary Analyzer of SQL Server 2000: ======================================= DECLARE @dTest DATETIME SET @dTest='2001-1-1 1:1:1:991' SELECT @dTest SET @dTest='2001-1-1 1:1:1:997' SELECT @dTest
0
1837
by: P Pulkkinen | last post by:
Dear all, sorry, i know this code is far little too long to debug here, but there is really annoying logical error. If someone debugs this, I really offer warm virtual handshake. What this code SHOULD do: - read new (=updated) licensetext from file $license_path then - read and modify recursively all files from $current_dir, replacing old
0
9856
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9698
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10910
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10589
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...
0
9426
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
7833
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
5683
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...
1
4493
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
3
3136
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.