faqcat1d60.html

来自「this is a mirrored site c-faq. thought 」· HTML 代码 · 共 2,607 行 · 第 1/5 页

HTML
2,607
字号
and a null pointer as the destination buffer.Therefore, the call<pre>	nch = snprintf(NULL, 0, fmtstring, /* other arguments */ );</pre>computesthe number of characters requiredfor the fully-formattedstring.With that number(<TT>nch</TT>)in hand,you can then malloc a big-enough bufferand make a second <TT>snprintf</TT> call to fill it.</p><p>Yet another option isthe (nonstandard) <TT>asprintf</TT> function,present in various C libraries including bsd's and GNU's,which formats to(and returns a pointer to)a <TT>malloc</TT>'ed buffer,like this:<pre>char *buf;asprintf(&amp;buf, "%d = %s", 42, "forty-two");/* now buf points to malloc'ed space containing formatted string */</pre></p><p>Additional links:<a href="../../stdio/asprintf.c">sample implementation of <TT>asprintf</TT></a></p><p>References:C9X Sec. 7.13.6.6<hr><hr><hr><a name="sprintfret"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/sprintfret.html"><!-- qtag -->Question 12.22</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's the deal on <TT>sprintf</TT>'s return value?Is it an <TT>int</TT> or a <TT>char&nbsp;*</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>The Standardsaysthat it returns an<TT>int</TT>(the number of characters written,just like <TT>printf</TT> and <TT>fprintf</TT>).Once upon a time,in some C libraries,<TT>sprintf</TT>returnedthe <TT>char&nbsp;*</TT> value of its first argument,pointingto thecompletedresult(i.e. analogous to <TT>strcpy</TT>'s return value).</p><p>References:ISO Sec. 7.9.6.5<br>PCS Sec. 11 p. 175<hr><hr><hr><a name="getsvsfgets"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/getsvsfgets.html"><!-- qtag -->Question 12.23</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>Why does everyone say not to use <TT>gets()</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Unlike <TT>fgets()</TT>,<TT>gets()</TT>cannot be told the size of the buffer it's to read into,so itcannot be prevented from overflowingthatbufferif an input line is longer than expected--andMurphy's Law says that,sooner orlater,a larger-than-expected input line <em>will</em> occur.<a href="../../stdio/rtmworm.html" rel=subdocument>[footnote]</a>(It's possible to convince yourself that,for some reason or another,input lines longer than some maximum are impossible,but it's also possible to bemistaken,<a href="../../stdio/oslinelen.html" rel=subdocument>[footnote]</a>and in any case it's justas easy to use <TT>fgets</TT>.)</p><p>The Standard <TT>fgets</TT> functionis a vast improvement over <TT>gets()</TT>,although it's not perfect, either.(If long lines are a real possibility,their proper handling must be carefully considered.)</p><p>One other difference between <TT>fgets()</TT> and <TT>gets()</TT>is that <TT>fgets()</TT> retains the <TT>'\n'</TT>,but it is straightforward to strip it out.See question<a href="faqcatbafd.html?sec=malloc#malloc1">7.1</a> for a code fragment illustratingthe replacement of <TT>gets()</TT> with <TT>fgets()</TT>.</p><p>References:Rationale Sec. 4.9.7.2<br>H&amp;S Sec. 15.7 p. 356<hr><hr><hr><a name="printferrno"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/printferrno.html"><!-- qtag -->Question 12.24</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I thought I'd check <TT>errno</TT>after a long string of <TT>printf</TT> calls,to see if any of them had failed:<pre>	errno = 0;	printf("This\n");	printf("is\n");	printf("a\n");	printf("test.\n");	if(errno != 0)		fprintf(stderr, "printf failed: %s\n", strerror(errno));</pre>Why is it printingsomething strange like``printf failed: Not a typewriter''when I redirect the output to a file?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Many implementations of the stdio package adjust theirbehavior slightly if <TT>stdout</TT> is a terminal.To make the determination,theseimplementations performsomeoperation whichhappens tofail(withENOTTY)if <TT>stdout</TT> is not a terminal.Although the output operation goeson to complete successfully, <TT>errno</TT> still containsENOTTY.This behavior can be mildly confusing, but it is notstrictly incorrect, becauseitis only meaningful for aprogram to inspect the contents of <TT>errno</TT> after an error hasbeen reported.(Moreprecisely,<TT>errno</TT> is only meaningfulafter a library functionthat sets <TT>errno</TT> on errorhas returned an error code.)</p><p>In general,it's best to detect errors by checkinga function'sreturn value.To check for anyaccumulatederror after a long string of stdio calls,you can use <TT>ferror</TT>.See also questions<a href="faqcat1d60.html?sec=stdio#feof">12.2</a>and<a href="faqcat38c2.html?sec=misc#errno">20.4</a>.</p><p>References:ISO Sec. 7.1.4, Sec. 7.9.10.3<br>CT&amp;P Sec. 5.4 p. 73<br>PCS Sec. 14 p. 254<hr><hr><hr><a name="fgetpos"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fgetpos.html"><!-- qtag -->Question 12.25</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>What's the difference between <TT>fgetpos</TT>/<TT>fsetpos</TT>and <TT>ftell</TT>/<TT>fseek</TT>?<br>What are <TT>fgetpos</TT> and <TT>fsetpos</TT> good for?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font><TT>ftell</TT> and <TT>fseek</TT>use type <TT>long&nbsp;int</TT>to representoffsets(positions)in a file,andmay therefore belimited to offsetswhich can be represented in a <TT>long&nbsp;int</TT>.(Type <TT>long&nbsp;int</TT> is not guaranteed to hold values largerthan2**31-1,limiting the maximumoffsetto 2 gigabytes).The newer<TT>fgetpos</TT> and <TT>fsetpos</TT>functions,on the other hand,use aspecialtypedef,<TT>fpos_t</TT>,to represent the offsets.The type behind this typedef,if chosen appropriately,can represent arbitrarily large offsets,so <TT>fgetpos</TT> and <TT>fsetpos</TT> can be used witharbitrarily huge files.<TT>fgetpos</TT> and <TT>fsetpos</TT> alsorecordthe state associated with multibyte streams.Seealso question <a href="faqcatd3c2.html?sec=decl#octabyte">1.4</a>.</p><p>References:K&amp;R2 Sec. B1.6 p. 248<br>ISO Sec. 7.9.1, Secs. 7.9.9.1,7.9.9.3<br>H&amp;S Sec. 15.5 p. 252<hr><hr><hr><a name="stdinflush"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/stdinflush.html"><!-- qtag -->Question 12.26a</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I flush pending input so that a user's typeaheadisn't read at the next prompt?Will <TT>fflush(stdin)</TT>work?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font><TT>fflush</TT> is defined only for output streams.Since its definition of ``flush''is to complete the writing of buffered characters(not to discard them),discarding unread inputwould not be an analogous meaningfor <TT>fflush</TT> on input streams.See also question <a href="faqcat1d60.html?sec=stdio#stdinflush2">12.26b</a>.</p><p>References:ISO Sec. 7.9.5.2<br>H&amp;S Sec. 15.2<hr><hr><hr><a name="stdinflush2"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/stdinflush2.html"><!-- qtag -->Question 12.26b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>If <TT>fflush</TT> won't work,what can I use to flush input?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>It depends on what you're trying to do.If you're trying to get rid ofan unread newlineor other unexpected inputafter calling <TT>scanf</TT>(see questions <a href="faqcat1d60.html?sec=stdio#scanfinterlace">12.18a</a>-<a href="faqcat1d60.html?sec=stdio#scanfjam">12.19</a>),you really need to rewrite or replacethe call to <TT>scanf</TT>(see question <a href="faqcat1d60.html?sec=stdio#scanfprobs">12.20</a>).Alternatively, you can consume the rest of a partially-read linewith a simple code fragment like<pre>	while((c = getchar()) != '\n' &amp;&amp; c != EOF)		/* discard */ ;</pre></p><p>(You may also be able touse the curses <TT>flushinp</TT> function.)</p><p>There is no standard way to discard unread characters from astdio inputstream.Some vendors do implement <TT>fflush</TT>so that <TT>fflush(stdin)</TT> discards unread characters,although portable programscannot depend on this.(Some versions ofthe stdio libraryimplement <TT>fpurge</TT>or <TT>fabort</TT> callswhich do the same thing,but these aren't standard, either.)Note, too, that flushing stdio input buffersis not necessarilysufficient:unread characters can also accumulate in other, OS-level inputbuffers.If you're trying to actively discardinput(perhaps in anticipation of issuingan unexpectedpromptto confirm a destructive action,for which an accidentally-typed ``y'' could be disastrous),you'll haveto use a system-specific technique to detect the presence of typed-ahead input;seequestions<a href="faqcatea63.html?sec=osdep#cbreak">19.1</a>and <a href="faqcatea63.html?sec=osdep#readavail">19.2</a>.Keep in mind that users can become frustratedif you discard input that happened to be typedtoo quickly.</p><p>References:ISO Sec. 7.9.5.2<br>H&amp;S Sec. 15.2<hr><hr><hr><a name="fopenfp"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fopenfp.html"><!-- qtag -->Question 12.27</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I wrote this routine which is supposed to open a file:<pre>	myfopen(char *filename, FILE *fp)	{		fp = fopen(filename, "r");	}</pre>But when I call it like this:<pre>		FILE *infp;		myfopen("filename.dat", infp);</pre>the <TT>infp</TT> variablein the caller doesn't get set properly.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>Functions in C always receive copies of their arguments,so a function can never ``return'' a value to the caller by assigning to an argument.See question <a href="faqcatabdc.html?sec=ptrs#passptrinit">4.8</a>.</p><p>For this example,one fix is tochange <TT>myfopen</TT> to return a <TT>FILE&nbsp;*</TT>:<pre>	FILE *myfopen(char *filename)	{		FILE *fp = fopen(filename, "r");		return fp;	}</pre>and call it like this:<pre>		FILE *infp;		infp = myfopen("filename.dat");</pre>Alternatively,have <TT>myfopen</TT> accept a <em>pointer</em> to a <TT>FILE&nbsp;*</TT>(a pointer-to-pointer-to-<TT>FILE</TT>):<pre>	myfopen(char *filename, FILE **fpp)	{		FILE *fp = fopen(filename, "r");		*fpp = fp;	}</pre>and call it like this:<pre>		FILE *infp;		myfopen("filename.dat", &amp;infp);</pre><hr><hr><hr><a name="fopenmodec"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fopenmodec.html"><!-- qtag -->Question 12.28</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>I can't even get a simple <TT>fopen</TT> call to work!What's wrong withthis call?<pre>	FILE *fp = fopen(filename, 'r');</pre></p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font><TT>fopen</TT>'s mode argument must be a string,like <TT>"r"</TT>,not a characterlike <TT>'r'</TT>.See also question <a href="faqcate107.html?sec=charstring#strvschar">8.1</a>.<hr><hr><hr><a name="constrpath"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/constrpath.html"><!-- qtag -->Question 12.28b</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I open files with names like``<TT>file1</TT>'',``<TT>file2</TT>'',``<TT>file3</TT>'',etc.,where the numeric part is controlled by a variable?Basically I want ``<TT>file%d</TT>'',like <TT>printf</TT>.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>You want <TT>printf</TT>'s close cousin <TT>sprintf</TT>,which ``prints'' to a string:<pre>	char filename[FILENAME_MAX];	sprintf(filename, "file%d", i);	fp = fopen(filename, "r");</pre><hr><hr><hr><a name="fopenpath"><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><a href="../../stdio/fopenpath.html"><!-- qtag -->Question 12.29</a></h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font><TT>fopen</TT> is failing for certain pathnames.</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>See questions <a href="faqcatea63.html?sec=osdep#dospath">19.17</a> and <a href="faqcatea63.html?sec=osdep#fopenenv">19.17b</a>.<hr><hr><hr>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?