472,354 Members | 1,677 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,354 software developers and data experts.

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
123333333333333333
1233333333333333
fdkjghfgsfgkjsdf
fdkjghfgfgkjsdf
(^C)
$

Any feedback will be appreciated!
Cheers!

- Joseph
Nov 13 '05 #1
8 2290


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
123333333333333333
1233333333333333
fdkjghfgsfgkjsdf
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*******@netcourrier.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
123333333333333333
1233333333333333
fdkjghfgsfgkjsdf
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*******@freenet.de)
Nov 13 '05 #3
On 7 Nov 2003 04:31:20 -0800
ag*******@netcourrier.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
123333333333333333
1233333333333333
fdkjghfgsfgkjsdf
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*******@netcourrier.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*******@freenet.de)
Nov 13 '05 #8
Jeff <ag*******@netcourrier.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
123333333333333333
1233333333333333
fdkjghfgsfgkjsdf
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
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...
13
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...
1
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...
0
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...
6
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...
1
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...
0
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
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,...
3
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...
0
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...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it so the python app could use a http request to get...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...
0
by: Ricardo de Mila | last post by:
Dear people, good afternoon... I have a form in msAccess with lots of controls and a specific routine must be triggered if the mouse_down event happens in any control. Than I need to discover what...

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.