⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sprintfsize.html

📁 this is a mirrored site c-faq. thought might need offline
💻 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/stdio/sprintfsize.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:58:58 GMT --><head><meta name=GENERATOR content="faqproc"><title>Question 12.21</title><link href="scanfprobs.html" rev=precedes><link href="sprintfret.html" rel=precedes><link href="index.html" rev=subdocument></head><body bgcolor="#ffffff"><a href="scanfprobs.html" rev=precedes><img src="../images/buttonleft.gif" alt="prev"></a><a href="index.html" rev=subdocument><img src="../images/buttonup.gif" alt="up"></a><a href="sprintfret.html" rel=precedes><img src="../images/buttonright.gif" alt="next"></a>&nbsp;<a href="../index-2.html"><img src="../images/buttontop.gif" alt="top/contents"></a><a href="../search.html"><img src="../images/buttonsrch.gif" alt="search"></a><hr><p><!-- qbegin --><h1>comp.lang.c FAQ list<font color=blue>&middot;</font><!-- qtag -->Question 12.21</h1><p><font face=Helvetica size=8 color=blue><b>Q:</b></font>How can I tell how much destination buffer space I'll needfor an arbitrary <TT>sprintf</TT> call?How can I avoidoverflowingthe destination buffer with <TT>sprintf</TT>?</p><p><hr><p><font face=Helvetica size=8 color=blue><b>A:</b></font>When the format string being used with <TT>sprintf</TT> isknown andrelatively simple,you cansometimespredictabuffersize in an ad-hoc way.Ifthe formatconsists of one or two <TT>%s</TT>'s,you can count the fixedcharacters in the formatstring yourself(or let <TT>sizeof</TT> count them for you)and add in the result of calling <TT>strlen</TT>on the string(s) to be inserted.For example,tocompute the buffer size that the call<pre>	sprintf(buf, "You typed \"%s\"", answer);</pre>would need,you couldwrite:<pre>	int bufsize = 13 + strlen(answer);or	int bufsize = sizeof("You typed \"%s\"") + strlen(answer);</pre>followed by<pre>	char *buf = malloc(bufsize);	if(buf != NULL)		sprintf(buf, "You typed \"%s\"", answer);</pre>You canconservativelyestimate the size that <TT>%d</TT> will expand to withcode like:<pre>#include &lt;limits.h&gt;char buf[(sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1];sprintf(buf, "%d", n);</pre>This codecomputesthe number of characters requiredfor a base-8 representation of a number;a base-10 expansion is guaranteed to take as much room or less.(The <TT>+2</TT> takes care of truncation if the size is not amultiple of 3,and the <TT>+1+1</TT> leaves room for a leading <TT>-</TT>and a trailing <TT>\0</TT>.)Ananalogous techniquecould of course be used for <TT>long&nbsp;int</TT>,and the same buffer can obviously be used with<TT>%u</TT>, <TT>%o</TT>, and <TT>%x</TT>formatsas well.</p><p>When the format string is more complicated,orisnotevenknown until run time,predicting the buffer size becomes asdifficultas reimplementing <TT>sprintf</TT>,and correspondingly error-prone(and inadvisable).Alast-ditchtechniquewhich is sometimessuggestedis to use<TT>fprintf</TT> to print the same text to atemporary file,andthen tolook at <TT>fprintf</TT>'s return valueorthe size of the file(but see question <a href="../osdep/filesize.html">19.12</a>).(Using a temporary file for this applicationis admittedlyclumsy and inelegant,<a href="diskerr.html" rel=subdocument>[footnote]</a>but it's the only portable solutionbesides writing an entire <TT>sprintf</TT> format interpreter.If your system provides one,you canusea null or ``bit bucket'' devicesuch as<TT>/dev/null</TT> or <TT>NUL</TT>instead of a temporary file.)</p><p>If there'sanychance that the buffer might not be big enough,you won't want to call <TT>sprintf</TT>without some guaranteethat the buffer will not overflowand overwrite some other part ofmemory.If the format string is known,you can limit <TT>%s</TT> expansion by using<TT>%.</TT>N<TT>s</TT>for some N,or <TT>%.*s</TT>(see also question <a href="printfvwid.html">12.10</a>).</p><p>To avoidthe overflow problem,you can usea length-limited version of <TT>sprintf</TT>,namely <TT>snprintf</TT>.Itisused like this:<pre>	snprintf(buf, bufsize, "You typed \"%s\"", answer);</pre><TT>snprintf</TT>has been available in several stdio libraries(including GNU and 4.4bsd)for several years.Ithas finally beenstandardized in C99.</p><p>As an extra, added bonus,the C99 <TT>snprintf</TT> provides a wayto predict the size requiredfor an arbitrary <TT>sprintf</TT> call.C99's<TT>snprintf</TT> returnsthe number of characters it would have placed in the bufferif there were room,not just how many it did place.Furthermore,it may be called witha null pointeranda buffer sizeof 0and 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="asprintf.c">sample implementation of <TT>asprintf</TT></a></p><p>References:C9X Sec. 7.13.6.6<br></p><!-- aend --><p><hr><a href="scanfprobs.html" rev=precedes><img src="../images/buttonleft.gif" alt="prev"></a><a href="index.html" rev=subdocument><img src="../images/buttonup.gif" alt="up"></a><a href="sprintfret.html" rel=precedes><img src="../images/buttonright.gif" alt="next"></a>&nbsp;<a href="../questions.html"><img src="../images/buttontop.gif" alt="contents"></a><a href="../search.html"><img src="../images/buttonsrch.gif" alt="search"></a><br><!-- lastfooter --><a href="../about.html">about this FAQ list</a>&nbsp;<a href="../eskimo.html">about eskimo</a>&nbsp;<a href="../search.html">search</a>&nbsp;<a href="../feedback.html">feedback</a>&nbsp;<a href="copyright.html">copyright</a><p>Hosted by<a href="http://www.eskimo.com/"><img src="../../www.eskimo.com/img/link/eskitiny.gif" alt="Eskimo North"></a></body><!-- Mirrored from c-faq.com/stdio/sprintfsize.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 07:58:58 GMT --></html>

⌨️ 快捷键说明

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