faq 19.1

U

Uno

Ben said:
Nick Keighley said:
On 28 June, 00:17, Uno <[email protected]> wrote:
the supposedly broken main()
[as re-posted by Nick:]

| int main(void)
| {
| int i;
| if(tty_break() != 0)
| return 1;
| for(i = 0; i < 10; i++)
| printf(" = %d\n", tty_getchar());
| tty_fix();
| return 0;
|
|
|
| }


I agree that it could benefit form a re-write and at least one of the
changes I'd make is C-related and thus topical here. I think people
would be less often surprised if the loop were:

for(i = 0; i < 10; i++) {
printf(" = %d\r\n", tty_getchar());
fflush(stdout);
}

<snip>

Right. Alan's suggestion has, I believe the same effect as fflush, but
you also note the printw call, which I think is better. Why? Because
if what I read is true, then you want to do your whole I/O through
curses if you do it at all:

$ gcc -Wall -Wextra -lcurses p7.c -o out
$ indent -i3 p7.c
$ ./out
$ cat p7.c
#define _XOPEN_SOURCE 500
//#define _XOPEN_SOURCE_EXTENDED 1
#include <stdio.h>
#include <curses.h>
int
tty_break ()
{
initscr ();
cbreak ();
return 0;
}

int
tty_getchar ()
{
return getch ();
}

int
tty_fix ()
{
endwin ();
return 0;
}

int
main (void)
{
int i;
if (tty_break () != 0)
return 1;
for (i = 0; i < 10; i++)
{
printw (" = %d\n", tty_getchar ());
refresh ();
}
tty_fix ();
return 0;
}

// gcc -Wall -Wextra -lcurses p7.c -o out
$

I think this program is a much better one than the one Mr. Summit has
for his own specification:

As an example, here is a tiny test program which prints the decimal
values of the next

ten characters as they are typed, without waiting for RETURN. It is
written in terms of

three functions, as described, and is followed by implementations of
the three functions

for curses, classic Unix, System V Unix, and MS-DOS. (The on-line
archives associated with

this list contain a more complete set of functions.)

Ben, I don't want to talk forever about something that is going to cause
me a bunch of grief, but the whole idea of the faq's is that people get
on their way without having to bring it up again. I haven't ever
brought up curses before. How would I? Working through the clc faq was
my first exposure.

The original output, though apparently legal, was wretched. I wasn't
going to take that and bring it in front of comp.unix.programmer and say
hey let's all take a look at this.
 
U

Uno

Vincenzo said:
maybe you meant if (ch == 'p') ?


and fputc(b, stdin);

Thx:


$ gcc -Wall -Wextra p5.c -o out
$ ./out
k
k
s
s
h
h
p
p$ cat p5.c
#include <stdio.h>
char get_char (void);
void put_char (char);
int
main (void)
{
char ch;
while ((ch = get_char ()) > 0) /* yeah, I know... */
{
put_char (ch);
if ((ch == 'p'))
break;
}
return 0;
}
void
put_char (char b)
{
fputc (b, stdout);
}
char
get_char (void)
{
char c;
c = fgetc (stdin);
return c;
}
// gcc -Wall -Wextra p5.c -o out
$
 
K

Keith Thompson

Vincenzo Mercuri said:
maybe you meant if (ch == 'p') ?


and fputc(b, stdin);

I really don't think you want to be writing to stdin. (I see Uno
fixed that in a followup.)
 
V

Vincenzo Mercuri

Keith said:
I really don't think you want to be writing to stdin. (I see Uno
fixed that in a followup.)

Yes...actually i didn't notice the 'in' in 'stdin' in fputc...
(too many 'in's) and I still don't get what the point of the program is.
But eventually we will make it work out (hopefully) - laughs -
 
S

Seebs

1) Seebs isn't insufferable; I suffer him quite gladly. But then, he's
not a fool. I do find fools insufferable.

I might be a little confused sometimes, though.
2) It isn't "your" thread. It's a Usenet thread. You may or may not have
started it (I can't be bothered to look right now), but you don't get to
choose who replies to it.

Indeed.

But! He does now have available an easy way to never again get responses
from me: Stop changing his posting name. If he changes his name again,
it'll take me a week or two to be sure it's him again, and during that time
he'll probably get more responses he doesn't like.

I thought I'd suggested this when he was posting under one of the earlier
names, but maybe I forgot. Oh, well. There's always next time.

-s
 
V

Vincenzo Mercuri

Sorry for this. As Keith said, you fixed it
$ gcc -Wall -Wextra p5.c -o out
$ ./out
k
k
s
s
h
h
p
p$ cat p5.c

if you want the character 'p' not to be echoed to stdout
you can get it this way:

#include <stdio.h>

int put_char(int b)
{
return fputc(b, stdout);
}

int get_char(void)
{
return fgetc(stdin);
}

int main(void)
{
int ch;
while( ((ch = get_char()) != EOF) && (ch != 'p') )
put_char(ch);
return 0;
}


Cheers
 
N

Nick Keighley

#include <stdio.h>
char get_char (void);
void put_char (char);
int
main (void)
{
    char ch;
    while ((ch = get_char ()) > 0)   /* yeah, I know... */

you know what? I can see two problems and can imagine some people
would see a third

<snip>
 
N

Nick Keighley

On 29 June, 20:38, Vincenzo Mercuri <[email protected]>
wrote:

I still don't get what the point of the program is.
But eventually we will make it work out (hopefully) - laughs -

I think UNO doesn't understand what "this cannot be implemented in
standard C" actually means.
 
U

Uno

Richard said:
Whom are you addressing? I wrote the original comment, but the code that
I originally wrote alongside it has been borken by Uno.

My answer to your question depends on your answer to mine.

I thought the original comment droll, as the solution I seemed to be
looking for went right back to K&R.

At the same time I'm trying to work up this material, I'm also trying to
look more closely at functions, in particular ones that are primitive.

I just got a hold of good pdf documentation for curses here:

http://www.unix.org/version3/xcurses_contents.html

So, I won't be using getchar from stdio but rather getch(), and I'm
still working on what the analog of
while ((ch = get_char ()) > 0)
is, but over in c.u.p.

Cheers,
 
N

Nick Keighley

Whom are you addressing? I wrote the original comment, but the code that
I originally wrote alongside it has been borken by Uno.

My answer to your question depends on your answer to mine.

ah, I was assuming both the code and the comment were Uno's
 
N

Nick Keighley

ah, I was assuming both the code and the comment were Uno's

and you of course didn't get the type of ch wrong. Testing for >0
rather than != EOF probably isn't actually wrong. The third one was
that soem people (not me!) think assignments in the expression part of
an 'if' are wrong
 
K

Keith Thompson

Nick Keighley said:
and you of course didn't get the type of ch wrong. Testing for >0
rather than != EOF probably isn't actually wrong. The third one was
that soem people (not me!) think assignments in the expression part of
an 'if' are wrong

Testing for > 0 (assuming ch is an int and we're not on a weird
system with sizeof(int)==1) doesn't distinguish between EOF and a
null character on input.
 
U

Uno

Richard Heathfield wrote:

[re-ordered, for thematic reasons]
If I were actually writing a tutorial along these lines, I'd have
thought a lot harder about that, and probably come up with some example
programs that didn't include getchar!

While I was flailing about with this stuff, trying to attain a standard
solution with the tools you're stuck with I wrote this:

$ gcc -Wall -Wextra p5.c -o out
$ ./out
fjdsnbf,
fjdsnbf,
f
f
^C
$ cat p5.c
#include <stdio.h>
char get_char (void);
void put_char (char);
int
main (void)
{
char ch;
while ((ch = get_char ()) > 0) /* yeah, I know... */
{
put_char (ch);
if ((ch == 'p'))
break;
}
return 0;
}
void
put_char (char b)
{
fputc (b, stdout);
}
char
get_char (void)
{
char c;
c = fgetc (stdin);
return c;
}
// gcc -Wall -Wextra p5.c -o out
$

If you work this up into your own tutorial, you can use this as an
example of something that doesn't quite cut it. It's all legal C, but
this program doesn't have the fflush functionality, and in that respect
is just like the program in the faq that seebs loves, but this person
thinks needs to be fflushed down the toilet.
> Very true - but I was kinda stuck for a good solution, given the
> enforced absence of standard headers (which necessarily meant that I
> didn't have a definition for EOF). I could have used >= 0, of course,
> and that would perhaps have been a marginal improvement.
>

stdio.h is by my estimation the hardest of the standard libraries to
implement. (Plauger's hardest (by his own estimation) was math.h) One
of the macros that must be defined, like Keith says, is EOF. These are
the macros that Plauger uses in stdio.h:

/* macros */
#define NULL _NULL
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
#define BUFSIZ 512
#define EOF (-1)
#define FILENAME_MAX _FNAMAX
#define FOPEN_MAX _FOPMAX
#define L_tmpnam _TNAMAX
#define TMP_MAX 32
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define stdin _Files[0]
#define stdout _Files[1]
#define stderr _Files[2]

I think this listing is much cleaner than you would find if you delved
into your own machine's stdio.h, which, as far as I can tell, is a
non-solvable progression of #included files.

I would also like to bring up how Plauger deals with system-specific stuff:

/* stdio.h standard header */
#ifndef _STDIO
#define _STDIO
#ifndef _YVALS
#include <yvals.h>
#endif

He puts them in a header, tells the reader it is all the nasty bits, and
then continues. I find it strange that people can't comment on a
question with the premise that they're to avoid the non-standard header.

I still haven't found yvals.h yet. I've been reading the book for
months now.
 
N

Nick Keighley

Richard Heathfield wrote:

While I was flailing about with this stuff, trying to attain a standard
solution with the tools you're stuck with I wrote this:

IT CAN'T BE DONE

good grief, how many times...

[...]
#include <stdio.h>
char get_char (void);
void put_char (char);
int main (void)
{
    char ch;

INT !

you're trolling aren't you?
    while ((ch = get_char ()) > 0)   /* yeah, I know... */
      {
        put_char (ch);
        if ((ch == 'p'))
           break;
      }
    return 0;}

void put_char (char b)
{
    fputc (b, stdout);
}

char get_char (void)
{
    char c;
    c = fgetc (stdin);
    return c;
} [...]
If you work this up into your own tutorial, you can use this as an
example of something that doesn't quite cut it.

why? Why would anyone do that?

 It's all legal C, but
this program doesn't have the fflush functionality, and in that respect
is just like the program in the faq that seebs loves, but this person
thinks needs to be fflushed down the toilet.

and again, in english

 > Very true - but I was kinda stuck for a good solution, given the
 > enforced absence of standard headers (which necessarily meant that I
 > didn't have a definition for EOF). I could have used >= 0, of course,
 > and that would perhaps have been a marginal improvement.
 >

stdio.h is by my estimation the hardest of the standard libraries to
implement.  (Plauger's hardest (by his own estimation) was math.h)  One
of the macros that must be defined, like Keith says, is EOF.  These are
the macros that Plauger uses in stdio.h:

                /* macros */
#define NULL            _NULL
#define _IOFBF          0

<snip>

why did you post that? Do you think Richard is unaware of the likely
definition of EOF?
I think this listing is much cleaner than you would find if you delved
into your own machine's stdio.h, which, as far as I can tell, is a
non-solvable progression of #included files.

ITYM non-resolvable. This is obviously untrue.
I would also like to bring up how Plauger deals with system-specific stuff:

/* stdio.h standard header */
#ifndef _STDIO
#define _STDIO
#ifndef _YVALS
#include <yvals.h>
#endif

He puts them in a header, tells the reader it is all the nasty bits, and
then continues.  I find it strange that people can't comment on a
question with the premise that they're to avoid the non-standard header.
what?

I still haven't found yvals.h yet.  I've been reading the book for
months now.

it's a while since I read it. I'm pretty sure it's in there. Have you
tried the index?
 
U

Uno

pete said:
Uno said:
char
get_char (void)
{
char c;
c = fgetc (stdin);
return c;
}
// gcc -Wall -Wextra p5.c -o out
$

If you work this up into your own tutorial, you can use this as an
example of something that doesn't quite cut it. It's all legal C, but
this program doesn't have the fflush functionality,
and in that respect
is just like the program in the faq that seebs loves, but this person
thinks needs to be fflushed down the toilet.

Concerning:
char c;
c = fgetc (stdin);
char is the wrong type to store the return value of fgetc.

N869

int fgetc(FILE *stream);

Returns
[#3] If the end-of-file indicator for the stream is set, or
if the stream is at end-of-file, the end-of-file indicator
for the stream is set and fgetc returns EOF.

So with
#define EOF (-1)
, under what circumstances would the char version break?
 
S

Seebs

INT !

you're trolling aren't you?

I have been running out of better explanations. There are people as
stubborn about trying to learn as him, and there are people as stubborn
about not learning as him, but the only other time I've seen someone who
appeared to be both, it was wossname, the guy who was going to develop
a database because existing databases were not powerful enough, but
couldn't figure out why mismatched braces weren't compiling*.

-s
[*] Slight paraphrase.
 

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

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top