C - gets() function implementation help

B

brian

Hi everyone,

I am a newbie in C programming.
I have to make an implementation of gets() function from stdio.h, but
I am not sure where to start.

Please advice, any help is welcome.

Thank you,
Brian.
 
S

Seebs

I am a newbie in C programming.
I have to make an implementation of gets() function from stdio.h, but
I am not sure where to start.
Please advice, any help is welcome.

My first advice is: This is a bad assignment, because the gets()
function is inherently broken.

Your instructor may not know this, but strictly speaking, you're not
allowed to make a function named gets() -- that name is reserved. You
can try it, and it might even happen to work, but it's not really
the right thing to do.

Here's a thing to start with.

Describe what gets() does. What parameters does it take? What does
it return? What does it *DO*?

For instance, I might start out with something like:
The mygets() function takes as a parameter the address of a
buffer assumed to be large enough to hold any input data.
The function then gets characters from standard input until
it sees either EOF or a newline, at which point it null
terminates the string and returns. If no characters are
received before EOF, the function indicates an error.

That's not a very good spec -- see if you can find some of the flaws
in it and correct them.

Once you have the spec, it shouldn't be too hard to write the routine.

-s
 
M

Malcolm McLean

Hi everyone,

I am a newbie in C programming.
I have to make an implementation of gets() function from stdio.h, but
I am not sure where to start.

Please advice, any help is welcome.
Presumably you are allowed getchar.
Simply read characters into the buffer passed to your mygets(),
reading them one by one with getchar(). Stop when getchar() returns
either EOF or a newline. terminate the buffer with a nul, not
forgetting to suppress the trailing newline.

As others have pointed out, gets() will (probably) crash if you pass
it a buffer shorter than the line you read. Given the specifications,
there's no way to prevent this behaviour, so think of it as an
undesireable feature rather than a bug.
 
B

brian

My first advice is:  This is a bad assignment, because the gets()
function is inherently broken.

Your instructor may not know this, but strictly speaking, you're not
allowed to make a function named gets() -- that name is reserved.  You
can try it, and it might even happen to work, but it's not really
the right thing to do.

Here's a thing to start with.

Describe what gets() does.  What parameters does it take?  What does
it return?  What does it *DO*?

For instance, I might start out with something like:
        The mygets() function takes as a parameter the address of a
        buffer assumed to be large enough to hold any input data.
        The function then gets characters from standard input until
        it sees either EOF or a newline, at which point it null
        terminates the string and returns.  If no characters are
        received before EOF, the function indicates an error.

That's not a very good spec -- see if you can find some of the flaws
in it and correct them.

Once you have the spec, it shouldn't be too hard to write the routine.

-s

Thank you for your thorough advice.

For example a standard description of gets() function says:
The gets() function shall read bytes from the standard input stream,
stdin, into the array pointed to by s, until a <newline> is read or an
end-of-file condition is encountered. Any <newline> shall be discarded
and a null byte shall be placed immediately after the last byte read
into the array.

I would like to do the same. Some guy recommended me to use getc() and
a loop,
But I think I should to try to implement it without using standard
stdio.h function, just pure C programming, if you know what I mean....
What could you advice on that?
 
M

Malcolm McLean

But I think I should to try to implement it without using standard
stdio.h function, just pure C programming, if you know what I mean....
What could you advice on that?
The problem is implementing getchar(). Once ypu've done that, it's
trivial to build gets() on top.
I don't know exactly how the system works myself these days, but
essentially it goes something like this. The keyboard sends an
interrupt to the processor when a key is depressed, and another one
when it is released. In the interrupt routine, the processor can query
the state of the keyboard, finding out which keys are depressed. That
raw information is passed to a higher-level process, which translates
the pattern of physical key presses into a "keyborad buffer"
contianing a queue of characters. Applications level-programs then
extract characters from the queue. There's some system for sending the
right characters to the program which has keyboard focus at the time.

Virtually all of this programming can be done in C, or C with a few
extensions and assembly calls. However it's imossible to do it without
an intimate knowledge of the system. Whilst not excessively
complicated or difficult, it tends to be hard to find the information
and it's not very accessibly-presented, because very few people have a
need to write keyborad drivers.
 
S

Seebs

I would like to do the same. Some guy recommended me to use getc() and
a loop,
But I think I should to try to implement it without using standard
stdio.h function, just pure C programming, if you know what I mean....
What could you advice on that?

Don't. There's no such thing as "pure C programming" -- unless you mean
"using the standard library only, not any implementation-specific stuff".

In any given environment, there may well be a way to do whatever would
be done under the hood by something like getchar(). For instance, on
Unix-like systems, you could probably do this with read(2). ("(2)" is
an indicator of the section of the manual to look in, not an argument
to pass to read().) But this is a BAD thing to do when you're at a novice
level.

The *purest* C is when you use the standard library and no platform-specific
stuff. Any time you migrate away from that, you're migrating away from
pure C.

-s
 
K

Keith Thompson

Malcolm McLean said:
As others have pointed out, gets() will (probably) crash if you pass
it a buffer shorter than the line you read. Given the specifications,
there's no way to prevent this behaviour, so think of it as an
undesireable feature rather than a bug.

Or think of it as a bug in the requirement, rather than a bug in your
code.
 
B

Barry Schwarz

The problem is implementing getchar(). Once ypu've done that, it's
trivial to build gets() on top.
I don't know exactly how the system works myself these days, but
essentially it goes something like this. The keyboard sends an
interrupt to the processor when a key is depressed, and another one
when it is released. In the interrupt routine, the processor can query

That may be how it works on your system but my keyboard sends no
signals to the processor until enter is pressed. I wonder how it
works on the OP's system or if he even knows.
 
B

Barry Schwarz

Thank you for your thorough advice.

For example a standard description of gets() function says:
The gets() function shall read bytes from the standard input stream,
stdin, into the array pointed to by s, until a <newline> is read or an
end-of-file condition is encountered. Any <newline> shall be discarded
and a null byte shall be placed immediately after the last byte read
into the array.

I would like to do the same. Some guy recommended me to use getc() and
a loop,
But I think I should to try to implement it without using standard
stdio.h function, just pure C programming, if you know what I mean....
What could you advice on that?

It is extremely counter productive for a newcomer to try to
simultaneously learn both C and the internal workings of both the
hardware and operating system. Too many brand new concepts lead to
confusion, not understanding.

"Pure C programming" uses only the features described in the standard.
If you want to try to build a "complex" function (such as gets) using
only the more "basic" functions available (such as getchar), it is not
a completely unreasonable exercise. But to discard all standard
functions and try to use system specific tools eliminates one of the
major reasons for studying C in the first place, its ability to create
portable functions.
 
P

Phil Carmody

Barry Schwarz said:
That may be how it works on your system but my keyboard sends no
signals to the processor until enter is pressed.

That must suck for tetris. Or vi, or notepad. Or even a shell.
Or text entry in a browser window. Or keyboard shortcuts in
any gui program. Or basically almost anything. I would find such
a keyboard basically useless.

Are you _sure_?

Phil
 
S

Seebs

That must suck for tetris. Or vi, or notepad. Or even a shell.
Or text entry in a browser window. Or keyboard shortcuts in
any gui program. Or basically almost anything. I would find such
a keyboard basically useless.
Are you _sure_?

Could be a smart terminal -- such certainly exist. The keyboard I'm
typing this on is not electrically connected to the machine that's
running the editor I'm writing in -- and while right now it's sending signals
to that machine pretty much whenever I hit a key, it can also arrange
to send no signals until I hit enter on this machine over here.

But the canonical example was the old mainframe terminals which sent a
form, and then the terminal let you edit the form, and then send back
the entire form as a block.

-s
 
B

Barry Schwarz

That must suck for tetris. Or vi, or notepad. Or even a shell.
Or text entry in a browser window. Or keyboard shortcuts in
any gui program. Or basically almost anything. I would find such
a keyboard basically useless.

Are you _sure_?

It's called an IBM mainframe and I am sure. As for being useless,
there seems to be a significant body of evidence to the contrary. But
then, it wasn't designed for games. And I consider the ISPF editor I
use on it infinitely superior to both vi and Notepad but that is just
a personal opinion which will probably cause this thread to degenerate
into another "my favorite editor" religious war. (I understand your
points about the other applications but I don't see why it would
affect a shell. The ones I occasionally use on a Sun workstation
running some flavor of Solaris don't seem to do anything until I press
enter anyway.)
 
S

Seebs

(I understand your
points about the other applications but I don't see why it would
affect a shell. The ones I occasionally use on a Sun workstation
running some flavor of Solaris don't seem to do anything until I press
enter anyway.)

They can do fairly elaborate command-line editing and things like "when
I hit tab, expand the word I've just typed into the longest unique filename
matching it" or "when I hit /, start searching for previous commands
matching a pattern".

So they really are live/interactive at that point.

-s
 
S

Stefan Ram

Barry Schwarz said:
That may be how it works on your system but my keyboard sends no
signals to the processor until enter is pressed.

I can get some signal from my keyboard even if enter is not
pressed, one needs to press Ctrl-C (YMMV):

#include <stdio.h> /* puts */
#include <signal.h> /* signal, SIGINT, SIG_DFL */

static volatile int looping = 1;
static void h( int const sig ){ looping = 0; }

int main( void )
{ signal( SIGINT, h );
puts ( "looping ..." );
while ( looping );
puts ( "terminated." );
signal( SIGINT, SIG_DFL ); }
 
B

Barry Schwarz

It sounds quite difficult to use.

How do you know you haven't made mistake before you hit Enter?

The fact that no data has been sent to the processor doesn't mean you
can't read it on the screen. One might consider the screen as the
buffer where the data is held until Enter is pressed.
Typing a password with a conventional machine is also difficult but at least
you can see how many characters you've typed.

I assume by conventional you mean PC.

Believe it or not, there are real security people who say that
displaying those cute little asterisks is a bad idea. It allows any
over-the-shoulder lurker to see how many characters are in your
password, thus making attempts to hack the password easier.
Does the mouse work the same way, nothing happens until you click the
button?

My system doesn't actually use a mouse but - Since the cursor moves
when I type without any help from the processor, I wouldn't need the
processor to move the cursor using some pointing device either.
 
B

bartc

Barry Schwarz said:
That may be how it works on your system but my keyboard sends no
signals to the processor until enter is pressed. I wonder how it
works on the OP's system or if he even knows.

It sounds quite difficult to use.

How do you know you haven't made mistake before you hit Enter?

Typing a password with a conventional machine is also difficult but at least
you can see how many characters you've typed.

Does the mouse work the same way, nothing happens until you click the
button?
 
M

Malcolm McLean

The fact that no data has been sent to the processor doesn't mean you
can't read it on the screen.  One might consider the screen as the
buffer where the data is held until Enter is pressed.
In that case you have two processors, a little one which collects
input from the keyboard, marshalls it into an input line, and updates
the screen, and a big one which accepts the processed line input and
solves protein folding (or whatever), sending the results back to the
little processor which updates the scren.
 
S

Seebs

In that case you have two processors, a little one which collects
input from the keyboard, marshalls it into an input line, and updates
the screen, and a big one which accepts the processed line input and
solves protein folding (or whatever), sending the results back to the
little processor which updates the scren.

Right -- but your C code is running on the big processor.

-s
 
K

Keith Thompson

bartc said:
(Does it? What word am I thinking of at this minute? I'll give you a
clue: it's got 7 letters and not 6 or 8 or 9.

Any outside knowledge about my password is too much.
But maybe password input should allow extra, discarded, white space to fix
that.)

No thanks. What if a password actually contains whitespace?

Incidentally, I once used a system that would echo a dot for each
character of a password, but would echo a space for any spaces that
were actually part of the password.
 
S

Stefan Ram

Barry Schwarz said:
Believe it or not, there are real security people who say that
displaying those cute little asterisks is a bad idea. It allows any
over-the-shoulder lurker to see how many characters are in your
password, thus making attempts to hack the password easier.

I hate it when the ATM acknowledges keys with beeps,
because this way a bystander can know whether I really
pressed a key or just have made a sham finger movement
to confuse observers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,099
Messages
2,570,626
Members
47,237
Latest member
David123

Latest Threads

Top