📄 faqcat1d60.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN"><!-- This collection of hypertext pages is Copyright 1995-2005 by Steve Summit. --><!-- Content from the book "C Programming FAQs: Frequently Asked Questions" --><!-- (Addison-Wesley, 1995, ISBN 0-201-84519-9) is made available here by --><!-- permission of the author and the publisher as a service to the community. --><!-- It is intended to complement the use of the published text --><!-- and is protected by international copyright laws. --><!-- The on-line content may be accessed freely for personal use --><!-- but may not be published or retransmitted without explicit permission. --><!-- --><!-- this page built Sat Dec 24 21:47:46 2005 by faqproc version 2.7 --><!-- from source file stdio.sgml dated Wed Dec 21 13:07:57 2005 --><!-- corresponding to FAQ list version 4.0 --><html><!-- Mirrored from c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=stdio by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:58:05 GMT --><head><base ><meta name=GENERATOR content="faqproc"><title>Stdio</title></head><body bgcolor="#ffffff"><H1>12. Stdio</H1><a name="getcharc"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/getcharc.html"><!-- qtag -->Question 12.1</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's wrong withthis code?<pre>char c;while((c = getchar()) != EOF) ...</pre></p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>For one thing,thevariable to hold <TT>getchar</TT>'s return valuemust be an <TT>int</TT>.<TT>EOF</TT> is an``out of band'' return value from <TT>getchar</TT>:it is distinct from all possible <TT>char</TT> valueswhich <TT>getchar</TT> can return.(On modern systems,it does not reflect any actual end-of-file characterstored in a file;it is a signal that no more characters are available.)<TT>getchar</TT>'s return valuemust be stored in a variable larger than <TT>char</TT>so that it can hold all possible <TT>char</TT> values,<em>and</em> <TT>EOF</TT>.</p><p>Two failure modes are possibleif,as in the fragment above,<TT>getchar</TT>'s return valueis assigned toa<TT>char</TT>.</p><OL><li>Iftype<TT>char</TT> is signed,and if <TT>EOF</TT> is defined(as is usual)as -1,the character with the decimal value 255(<TT>'\377'</TT> or <TT>'\xff'</TT> in C)willbe sign-extended andwillcompare equal to <TT>EOF</TT>,prematurely terminating the input.<a href="../../stdio/char8b.html" rel=subdocument>[footnote]</a><li>Iftype <TT>char</TT> is unsigned,anactual<TT>EOF</TT>valuewill betruncated(by having its higher-order bits discarded,probably resulting in 255 or <TT>0xff</TT>)and will <em>not</em> be recognized as <TT>EOF</TT>,resulting in effectively infinite input.</OL><p>The bug can go undetected for a long time, however,if <TT>char</TT>s are signed and if the input is all 7-bit characters.(Whetherplain <TT>char</TT> is signed or unsignedis implementation-defined.)</p><p>References:K&R1 Sec. 1.5 p. 14<br>K&R2 Sec. 1.5.1 p. 16<br>ISO Sec. 6.1.2.5, Sec. 7.9.1, Sec. 7.9.7.5<br>H&S Sec. 5.1.3 p. 116, Sec. 15.1, Sec. 15.6<br>CT&P Sec. 5.1 p. 70<br>PCS Sec. 11 p. 157<hr><hr><hr><a name="eofval"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/eofval.html"><!-- qtag -->Question 12.1b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I have a simple little program that reads characters until EOF,but how do I actually <em>enter</em> that ``EOF'' valuefrom the keyboard?I see that <TT>EOF</TT> is defined by <TT><stdio.h></TT> to be -1;am I supposed to enter -1?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>If you think about it,what you enter <em>can't</em> be -1,because ``-1'' is two characters,and <TT>getchar</TT> is reading one character at a time.It turns out that the value of EOF as seen within your C programhas essentially nothing to do with the keystroke combination youmightuse to signal end-of-file from the keyboard.EOF is essentially a signal to your programthat no more characterswill be availablefrom that input,for <em>whatever</em> reason(end of a disk file,user is done typing,network stream has closed,I/O error, etc.).</p><p>Depending on your operating system,you indicate end-of-filefrom the keyboardusing various keystroke combinations,usually either control-D or control-Z.The operating system and stdio library then arrangethat your C program receive the EOF value.(Note, however, that there are various translations involved along the way.Under normal circumstances,you should <em>not</em> explicitly check forthe control-D or control-Z value yourself,nor will you find thatthe <TT><stdio.h></TT> macro<TT>EOF</TT> is defined to be either of these values.)<hr><hr><hr><a name="feof"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/feof.html"><!-- qtag -->Question 12.2</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Whydoesthesimple line-copying loop<TT>while(!feof(infp)) {fgets(buf, MAXLINE, infp);fputs(buf, outfp);}</TT>copythe last line twice?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>In C,end-of-fileis only indicated<em>after</em>an input routinehas tried to read, andfailed.(In other words,C's I/O is not like Pascal's.)Usually, you should just check the return valueof the input routine:<pre> while(fgets(buf, MAXLINE, infp) != NULL) fputs(buf, outfp);</pre>In virtually all cases,there's noneed to use <TT>feof</TT> at all.(<TT>feof</TT>,or more likely <TT>ferror</TT>,may be useful <em>after</em>a stdio call has returned <TT>EOF</TT> or <TT>NULL</TT>,to distinguish between an end-of-fileconditionand a read error.)</p><p>References:K&R2 Sec. 7.6 p. 164<br>ISO Sec. 7.9.3, Sec. 7.9.7.1, Sec. 7.9.10.2<br>H&S Sec. 15.14 p. 382<hr><hr><hr><a name="linebfdur"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/linebfdur.html"><!-- qtag -->Question 12.3</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I'm using <TT>fgets</TT> to readlines from a file into anarrayof pointers.Why do all the lines end up containing copies of the last line?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcatbafd.html?sec=malloc#linebfdur">7.4</a>.<hr><hr><hr><a name="fflush"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/fflush.html"><!-- qtag -->Question 12.4</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>My program's prompts and intermediate output don't always show upon the screen,especially when I pipe the output through another program.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>It's best to use an explicit <TT>fflush(stdout)</TT>wheneveroutput should definitely be visible(and especially if the textdoes not endwith <TT>\n</TT>).<a href="../../stdio/noflush.html" rel=subdocument>[footnote]</a>Several mechanismsattempt to perform the <TT>fflush</TT> for you,at the ``right time,''but theytend to apply onlywhen <TT>stdout</TT> isan interactiveterminal.(See also question<a href="faqcat1d60.html?sec=stdio#printferrno">12.24</a>.)</p><p>References:ISO Sec. 7.9.5.2<hr><hr><hr><a name="charatatime"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/charatatime.html"><!-- qtag -->Question 12.5</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I read one character at a time,without waiting for the RETURN key?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question<a href="faqcatea63.html?sec=osdep#cbreak">19.1</a>.<hr><hr><hr><a name="printfpercent"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/printfpercent.html"><!-- qtag -->Question 12.6</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I print a <TT>'%'</TT> characterin a <TT>printf</TT> format string?I tried <TT>\%</TT>, but it didn't work.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Simply double the percent sign:<TT>%%</TT> .</p><p>The reason it's tricky to print <TT>%</TT> signs with <TT>printf</TT>is that <TT>%</TT> is essentially <TT>printf</TT>'sescape character.Whenever <TT>printf</TT> sees a <TT>%</TT>,it expects it to be followed by a character telling it what to do next.The two-character sequence <TT>%%</TT>is definedtoprint a single <TT>%</TT>.</p><p>To understand why<TT>\%</TT> can't work,rememberthatthe backslash <TT>\</TT>is the <em>compiler's</em> escape character,andcontrols how the compiler interprets source code charactersat compile time.In this case,however,we want to control how <TT>printf</TT> interprets its format stringat run-time.As far as the compiler is concerned,the escape sequence <TT>\%</TT> is undefined,and probably results in a single <TT>%</TT> character.It would be unlikely for both the <TT>\</TT> and the <TT>%</TT> tomake itthrough to <TT>printf</TT>,even if <TT>printf</TT> were prepared totreatthe <TT>\</TT>specially.</p><p>Additional links:<a href="faqcat1d60.html?sec=stdio#cescapes">further reading</a></p><p>See alsoquestions <a href="faqcate107.html?sec=charstring#runtimesc">8.8</a> and <a href="faqcatea63.html?sec=osdep#dospath">19.17</a>.</p><p>References:K&R1 Sec. 7.3 p. 147<br>K&R2 Sec. 7.2 p. 154<br>ISO Sec. 7.9.6.1<hr><hr><hr><a name="printftypes"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/printftypes.html"><!-- qtag -->Question 12.7</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why doesn't<pre>long int n = 123456;printf("%d\n", n);</pre>work?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Whenever you print <TT>long int</TT>s you must usethe <TT>l</TT>(lower case letter ``ell'')modifier in the printf format(e.g. <TT>%ld</TT>).<TT>printf</TT> can't know the types of the argumentswhich you've passed to it,so you must let it knowby using the correct format specifiers.<hr><hr><hr><a name="varargproto"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/varargproto.html"><!-- qtag -->Question 12.8</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I thought that ANSI function prototypeswere supposed to guard against argument type mismatches.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See question <a href="faqcat744e.html?sec=varargs#proto2">15.3</a>.<hr><hr><hr><a name="scanfvsprintf"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/scanfvsprintf.html"><!-- qtag -->Question 12.9</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Someone told me it was wrong to use <TT>%lf</TT> with <TT>printf</TT>.How can<TT>printf</TT> use <TT>%f</TT> for type <TT>double</TT>,if <TT>scanf</TT> requires <TT>%lf</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>It's true that <TT>printf</TT>'s <TT>%f</TT> specifierworks with both <TT>float</TT> and <TT>double</TT>arguments.<a href="../../stdio/fpfmts.html" rel=subdocument>[footnote]</a>Due to the``default argument promotions''(which apply in variable-length argument lists<a href="../../stdio/argpromo.html" rel=subdocument>[footnote]</a>such as<TT>printf</TT>'s,whether or not prototypes are in scope),values of type <TT>float</TT> are promoted to <TT>double</TT>,and <TT>printf</TT> therefore sees only <TT>double</TT>s.(<TT>printf</TT> does accept <TT>%Lf</TT>, for <TT>long double</TT>.)See also question<a href="faqcat744e.html?sec=varargs#promos">15.2</a>.</p><p><TT>scanf</TT>, on the other hand,accepts pointers,and no such promotions apply.Storing into a <TT>float</TT>(via a pointer)is very different fromstoring into a <TT>double</TT>,so <TT>scanf</TT> distinguishes between <TT>%f</TT> and <TT>%lf</TT>.</p><p>Here is a table listing the argument typesexpected by <TT>printf</TT> and <TT>scanf</TT>for the various format specifiers:<blockquote>[TABLE GOES HERE]</blockquote></p><p>(Strictly speaking,<TT>%lf</TT> is undefinedunder <TT>printf</TT>,thoughmanysystems probably accept it.To be portable,alwaysuse <TT>%f</TT>.)</p><p>See also question <a href="faqcat1d60.html?sec=stdio#scanf2">12.13</a>.</p><p>References:K&R1 Sec. 7.3 pp. 145-47, Sec. 7.4 pp. 147-50<br>K&R2 Sec. 7.2 pp. 153-44, Sec. 7.4 pp. 157-59<br>ISO Sec. 7.9.6.1, Sec. 7.9.6.2<br>H&S Sec. 15.8 pp. 357-64, Sec. 15.11 pp. 366-78<br>CT&P Sec. A.1 pp. 121-33<hr><hr><hr><a name="printftypedef"><h1>comp.lang.c FAQ list<font color=blue>·</font><a href="../../stdio/printftypedef.html"><!-- qtag -->Question 12.9b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What <TT>printf</TT> format should I use for a typedeflike <TT>size_t</TT>when I don't knowwhether it's <TT>long</TT> or some other type?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Use a cast to convert the value to a known, conservatively-sizedtype,then use the <TT>printf</TT> format matching that type.For example, to print the size of a type,you might use<pre> printf("%lu", (unsigned long)sizeof(thetype));</pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -