baron@bnlux0.bnl.gov (ed baron) (04/01/89)
Maybe this isn't the best place to post this but it seemed reasonable.
I am trying to learn c out of a book that seems to be wrong on many
things, but anyway i can't seem to figure out how getchar() should
work. consider the following
char name [10];
int c;
for(;;)
{
puts("enter 9 to exit");
c = getchar();
if(c == 9)
break;
puts("enter name: ");
gets(name);
.
.
.
}
now getchar gets one character but not until it sees the terminator
(carriage return) but since it only gets one character and the
carriage return is one character if you enter 1<cr> say
the <cr> is passed to the next thing seeking input and so now
name is just <cr> i.e there is no opportunity to respond to the naame
prompt. then i tried using gets(c) in place of getchar c (andd
declaring c to be char) but that won't compile. what is the proper
way to do this? please respond via mail. thanks.
ed baron (baron@bnlux0.bnl.gov, baron@bnlux0.bitnet)
matthew@sunpix.UUCP ( Sun NCAA) (04/03/89)
In article <1091@bnlux0.bnl.gov>, baron@bnlux0.bnl.gov (ed baron) writes: } Maybe this isn't the best place to post this but it seemed reasonable. } } I am trying to learn c out of a book that seems to be wrong on many } things, but anyway i can't seem to figure out how getchar() should } work. consider the following } } char name [10]; } int c; } } for(;;) } { } puts("enter 9 to exit"); } c = getchar(); } if(c == 9) } break; } puts("enter name: "); } gets(name); } . } . } . } } } } now getchar gets one character but not until it sees the terminator } (carriage return) but since it only gets one character and the } carriage return is one character if you enter 1<cr> say } the <cr> is passed to the next thing seeking input and so now } name is just <cr> i.e there is no opportunity to respond to the naame } prompt. then i tried using gets(c) in place of getchar c (andd } declaring c to be char) but that won't compile. what is the proper } way to do this? please respond via mail. thanks. } } ed baron (baron@bnlux0.bnl.gov, baron@bnlux0.bitnet) I know your problem well. What you are looking for is a 'getch()' or 'getche()' function in place of the 'getchar()' function. Barring that try c = getchar(); fflush(stdin); The variable 'c' will get the first character of input, and the remainder of the line (plus the newline) will get flushed away. -- Matthew Lee Stier | Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee" uucp: { sun, mcnc!rti }!sunpix!matthew | phone: (919) 469-8300 fax: (919) 460-8355 |
dhesi@bsu-cs.UUCP (Rahul Dhesi) (04/04/89)
In article <584@greens.UUCP> matthew@sunpix.UUCP ( Sun NCAA) writes: >c = getchar(); >fflush(stdin); > >The variable 'c' will get the first character of input, and the remainder >of the line (plus the newline) will get flushed away. Some time ago I noticed that people were assuming that fflush() would flush pending input data from a file open for reading. Apparently many implementations of stdio do this. I don't think portable code should rely on it. The Turbo C 1.0 manual says fflush() on a stream open for reading flushes the contents of the buffer. If the stream is line-buffered the rest of the line will indeed be flushed. However, the 4.3BSD documentation and my (slightly outdated) System V Interface Definition both say only that fflush() works on streams opened for writing. Streams open for reading are not mentioned in this context. /* portably read one char and ignore rest of line */ c = getchar(); while (!feof(stdin) && getchar() != '\n') ; I don't know what the ANSI standard says, but for now it probably doesn't matter. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi ARPA: dhesi@bsu-cs.bsu.edu
ark@alice.UUCP (Andrew Koenig) (04/04/89)
In article <584@greens.UUCP>, matthew@sunpix.UUCP ( Sun NCAA) writes: > I know your problem well. What you are looking for is a 'getch()' or > 'getche()' function in place of the 'getchar()' function. Barring that try > c = getchar(); > fflush(stdin); Why depend so intimately on the detailed behavior of the C run-time library? Not all implementations support fflush(stdin). The following is much more portable: c = getchar(); if (c != '\n') while (getchar() != '\n') ; -- --Andrew Koenig ark@europa.att.com
guy@auspex.auspex.com (Guy Harris) (04/04/89)
>I don't know what the ANSI standard says, but for now it probably >doesn't matter. It says that the behavior is undefined if you do an "fflush" on an read-only stream or a read/write stream in which the most recent operation was not an input operation. Translation: "fflush" doesn't flush input, so the ANSI standard says nothing new - it says "it flushes output, we make no claims about input", which reflects current practice (S5R3's "fflush" appears to flush input, although it's not documented - which is kind of obnoxious; either it's a useful feature, in which case it should be documented and supported, or it's a useless one, in which case it shouldn't have been put in; 4.3-tahoe's doesn't; Turbo C's is documented as doing so and presumably does; etc..)
guy@auspex.auspex.com (Guy Harris) (04/04/89)
> I know your problem well. What you are looking for is a 'getch()' or >'getche()' function in place of the 'getchar()' function. Huh? What would those functions do? They're not in the ANSI C standad nor are they in any UNIX C library. If they're a PCism, note that plenty of C programs have never programmed on a PC and, as such, may not be familiar with them. >Barring that try > >c = getchar(); >fflush(stdin); > > The variable 'c' will get the first character of input, and the remainder >of the line (plus the newline) will get flushed away. Bad idea, as Rahul Dhesi has already pointed out: 1) "fflush(stdin)" is not guaranteed to flush input on all implementations; 2) even if it does do so on your implementation, it may or may not stop at the end of the line in all cases. Much better to *read* the rest of the line, as in Rahul's posting. Not only is it portable, it's the right thing to do - flushing input is generally an action taken on an error, not something you do as a matter of course unless you want to make *sure* somebody hasn't typed something ahead that they'll regret (cf. "rn", which does flush input for precisely that reason).
chris@mimsy.UUCP (Chris Torek) (04/05/89)
In article <1384@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes: >... flushing input is generally an action taken on an error, not >something you do as a matter of course unless you want to make *sure* >somebody hasn't typed something ahead that they'll regret (cf. "rn", >which does flush input for precisely that reason). ... *and* which provides a flag (-T) to turn off this behaviour! Some of us find ignoring input obnoxious. If you are going to do it, please make sure there is a way to defeat it as well. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@smoke.BRL.MIL (Doug Gwyn) (10/22/89)
In article <456@s5.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes: >OK, so how can I avoid following commonly available bad rules or >mispractices in C programming? ... I am not satisfied with writing >merely functional programs; I want them to be clear and clean and >run everywhere. I want them to be easy to maintain and upgrade. >Where can I turn to get the kind of advice ...? Harbison & Steele is okay. My personal favorite is Kernighan & Ritchie, which teaches these things more by refusing to teach the contrary than by making a lot of noise about it. Plum Hall (1 Spruce Av, Cardiff NJ 08232, (609)927-3770) are probably the oldest firm specializing in C instruction, and they publish some very good C programming texts that go into more detail in these areas than K&R. I have heard good reports also about Lapin's book on portable C programming, but I haven't reviewed it. Many of the tricks of the trade have been explained by several experienced C programmers in this newsgroup. There is of course also a lot of silliness, bad advice, and just plain noise here. You need to evaluate the suggestions for yourself and develop a notion of who the reliable sources are. >Also: is there a logical exegesis of a fairly full subset of C? >For example, a set of proof rules in the literature somewhere? Not so far as I know, although you might check an index to SIGPLAN Notices. A company called Metaware has produced a formal semantic specification for one full dialect of C; their compiler is derived from it. However, I'm rather skeptical of the practical value of such work for the concerns that you have. >I have for years been complaining about the difficulty of unbound >pointers in this regard, but I am perhaps out of date. (Did the >ANSI standardization affect this problem? I'm pretty sure it >didn't, but I cannot give an authoritative reference.) Tell me what the problem IS, and perhaps I can answer. Remember that C's emphasis is less academic and more practical than most programming languages. Just because a clean theoretical model wouldn't fully cover all valid uses of pointers in C doesn't mean that there is necessarily a practical problem with its pointer facility. >There have been graduate courses for years where every jot and tittle >of PL/I or Algol 68 are thrashed out in agonizing detail. Anyone >ever done this for C? Gee, I certainly hope not. That's not a topic worthy of being made into a graduate course. >... I just want to know where can I get the straight dope on C short >of the standard itself, (if possible). The Standard defines the language, and it's relatively readable (in fact, using English could be considered a deficiency); the accompanying Rationale document helps one understand why some things were specified the way they were. (Most of the rest are understandable as directly reflecting the committee's charter.) The book "Standard C" by P.J. Plauger and Jim Brodie (Microsoft Press, 16011 NE 36th Way, Box 97017, Redmond WA 98073-9717), ISBN 1-55615-158-6, constitutes a very thorough description of Standard C, probably the closest you're going to find to an "exegesis". Keep in mind that Standard C is a recent development, and there are numerous compilers still in use that support some old-fashioned C dialect unstead of Standard C. Therefore, for practical purposes you ought to consider the impact of older C environments when you develop software that might be ported to them. With any luck, this will be a rather minor consideration after a couple more years.
mcdonald@uxe.cso.uiuc.edu (10/25/89)
From the well-known jlg: >However, my _POINT_ was that, if the short circuit nature of these >operators is valuable, then there might also be other contexts where >user control of expression evaluation order might _ALSO_ be valuable! >C doesn't provide such other mechanisms - WHY NOT?!?!?!? Ummm- the user always has control of evaluation order in && and || constructs. And any other place too, by use of temporary variables. I thought this flame war was over the inability of the compiler to optimize evaluation order in && and || constructs.
jlg@lanl.gov (Jim Giles) (10/25/89)
From article <225800228@uxe.cso.uiuc.edu>, by mcdonald@uxe.cso.uiuc.edu: > Ummm- the user always has control of evaluation order in && and || > constructs. And any other place too, by use of temporary variables. > I thought this flame war was over the inability of the compiler > to optimize evaluation order in && and || constructs. This _discussion_ is about whether C has _efficient_ means of forcing evaluation order in _several_ contexts (the first was the order of argument evaluation in a function call). Temporary variables are _not_ an efficient solution (unless they are optimized out - something C compilers are rarely clever enough to do). Temporary variables also have a negative impact on readibility (by diffusing the 'locality' of specific operations). Now a "flame war" would be an exchange with no technical content in which the participants used phrases like "you're an ignorant @#$#%@ who doesn't know his #$@ from a $#@%$!!". I have tried, at least, to keep above that level (so far anyway).
ok@cs.mu.oz.au (Richard O'Keefe) (10/25/89)
In article <14117@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > This _discussion_ is about whether C has _efficient_ means of forcing > evaluation order in _several_ contexts (the first was the order of > argument evaluation in a function call). It is impossible to conduct such a discussion. A language may have complex or concise or clear or confusing or direct or indirect means of expressing something, but efficiency is a property of implementations, not of languages. > Temporary variables are > _not_ an efficient solution (unless they are optimized out - something > C compilers are rarely clever enough to do). This is confusing two levels: languages and implementations. Heck, "a := a+1" should be efficiently implemented, but I know of one Ada compiler for the NS32000 that generates 8 instructions for it (not a commercial product; it was reported in SP&E 1987; they hadn't put the peephole optimiser in yet). If C compilers X, Y, and Z don't optimise out temporary variables, complain about compilers X, Y, and Z, not about C. If the vendors of compilers X, Y, and Z independently explain that the optimisation is hard because of property P of the language, complain then abou property P of the language. > Temporary variables also > have a negative impact on readibility (by diffusing the 'locality' of > specific operations). Well, that depends. To start with, temporary variables have the great merit of being a familiar means. That's how you force argument evaluation order in Algol 60, Pascal, Ada, Fortran (66, 77, 8X), Modula, Lisp, Simula 67, ... The technique also has the merit of making the order of evaluation obvious. There is a further point that if expression E1 has to be evaluated before expression E2, it makes it a whole lot simpler to explain in the comments *why* E1 has to be evaluated before E2 if you have names for the results. Finally, I was taught years and years ago that a complicated expression should be broken up into medium-sized pieces (such as could be given meaningful names) *to make it more readable*.
mcdonald@uxe.cso.uiuc.edu (10/25/89)
>The C standard has been through 3 public reviews and is presently facing >a class-action suit. It is still not an official standard. This does >not qualify as "a reality" in my book. Class action suit? This sounds interesting. Let's hear more. Flames to comp.lang.c.national.enquirer.
jlg@lanl.gov (Jim Giles) (10/26/89)
From article <2523@munnari.oz.au>, by ok@cs.mu.oz.au (Richard O'Keefe): > Well, that depends. To start with, temporary variables have the great > merit of being a familiar means. That's how you force argument > evaluation order in Algol 60, Pascal, Ada, Fortran (66, 77, 8X), Modula, > Lisp, Simula 67, ... Most of those languages also have _other_ means of forcing evaluation order in useful contexts. For example, all of the above mentioned languages allow the user to prohibit optimization of expressions involving associative operators - using parenthesis. The C argument that parenthesis should be used _only_ for legibility always seemed rather silly (especially in a language which otherwise makes so few concessions for legibility).
ok@cs.mu.oz.au (Richard O'Keefe) (10/26/89)
In article <14124@lanl.gov>, jlg@lanl.gov (Jim Giles) writes:
: From article <2523@munnari.oz.au>, by ok@cs.mu.oz.au (Richard O'Keefe):
: > Well, that depends. To start with, temporary variables have the great
: > merit of being a familiar means. That's how you force argument
: > evaluation order in Algol 60, Pascal, Ada, Fortran (66, 77, 8X), Modula,
: > Lisp, Simula 67, ...
:
: Most of those languages also have _other_ means of forcing evaluation
: order in useful contexts. For example, all of the above mentioned
: languages allow the user to prohibit optimization of expressions
: involving associative operators - using parentheses. The C argument
: that parentheses should be used _only_ for legibility always seemed
: rather silly
Working backwards:
- last time I heard about the ANSI draft it *did* require that
parentheses be respected a la Fortran
- I've never heard of any "C argument that parentheses should be used
only for legibility". On the contrary, the C argument was that
parentheses had to be used so heavily in macros to protect against
context that it was better they should have only syntactic force
- Lisp is one of "the above mentioned languages" and it most certainly
does NOT allow the user to prohibit expression optimisation using
parentheses (parentheses make lists!)
- there seems to be a confusion between association and order of
elaboration. In reading this thread, whenever Giles has written about
"argument evaluation order" I had assumed that he was talking about
things like
in f(x) + g(x), is f() called then g(), or g() called then f()?
What made me think this was the discussion of the order of evaluation
of arguments to functions.
Parentheses in Algol, Fortran, Pascal, Ada, and the rest have NO
relevance to that question. What parentheses force is association:
(A + B) + C
must be calculated as
add A, B giving temp
add temp, C giving result
However, the values of A, B, and C may be calculated in any order.
This is relevant when it comes to function calls. Consider
( P(X) .AND. Q(X) ) .AND. R(X)
in Fortran. It is legal for a Fortran compiler to generate code
equivalent to
t1 = q(x);
t2 = r(x);
t3 = p(x);
result = (t3 & t1) & t2
The parentheses control the order in which the values of the leaves of
the expression tree are combined, but not the order in which the values
of those leaves are obtained.