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 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 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)
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.
> 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
Oups, sorry about the error, it should be printf ("%s", s);
- Joseph
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. 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)
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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;
|
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,...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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++...
|
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...
|
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...
|
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...
| |