本文介绍了snprintf()返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! C99标准以一种尴尬的方式描述了snprintf(),所以很难(b)对我来说(在我看来)假设在某些情况下结果会是什么。 1.描述部分状态: " ...否则,超出n-1的输出字符将被丢弃而不是写入数组,并且写入空字符 实际写入数组的字符的结尾。 2.返回部分状态: " snprintf函数返回的字符数已经写入了足够大的,不计算 终止空字符,如果发生编码错误 ,则返回负值。因此,当且仅当返回值为非负且小于n时,空终止输出已完全写入 。 请考虑以下内容代码: #include< stdio.h> int main(无效) { int r; double d = -10; char str [5]; r = snprintf(str, 5,%f,d); printf(" r =%d str =%s \ n",r,(r 0&& r< 5) ?str:"< INVALID>"); 返回0; } 由于缺少精度,它被视为6,但snprintf()进一步 限制它。我的问题是,这个 案例的回报值应该是多少: a)5,str包含-10。 b)5(双精度所需的字符数,因为它是不适合str) ,str内容无效 c)-1由于编码错误,str内容无效 d)我错过的其他东西 我的假设是5,但似乎是不正确的。以下 是来自不同系统的结果: gcc 3.3(Mac OS X):10 gcc 3.4.5(Windows,mingw ): - 1 BC ++ 5.5.1(Windows):10 DigitalMars 8.42n(Windows): - 1 我也想知道编码错误是什么表示在snprintf() 的情况下。它通常与多字节/宽字符有关吗? - WYCIWYG - 你得到的是什么? class =h2_lin>解决方案 返回值应为10,因为那是多少个字符(没有 尾随的''\ 0'')在-10.000000中,你得到的字符串为 unadorned"%f"用-10。 arry''str''只包含这10个字符中的多个 符合字符串(包括tra $ ling''\ 0''' ),所以它将是-10。在你的情况下。这允许你使用snprintf()来找出你需要多少个字符来支持需要的东西 - 只需用0作为第二个参数来调用它,它就会给你 字符串的strlen()将导致snprintf()完全成功 - ful调用。这个数字然后可以用来为结果字符串分配 完全相同的内存(然后你就可以使用可能稍微快一点的sprintf(); - ) 看起来好像其中一些编译器使用了不兼容的libc。 一些sprintf()的第一个实现(在 C99标准之前,例如GNU libc 5)确实返回-1,如果 结果字符串不适合内存允许写作。 在您测试的所有实现中,这种旧行为似乎没有得到纠正 。 是的。据我所知,你会得到一个编码错误。如果你是请求snprintf()使用%ls打印出一个wchar_t字符串,但 该字符串确实包含无效宽字符的数据。 /> 问候,Jens - \ Jens Thoms Toerring ___ [email protected] \ __________________________ http:// toerring .de 10是正确的结果。简而言之,微软的snprintf版本已经损坏了(他们的文档甚至声称如果要写入的字符数超过缓冲区,snprintf会返回负值 值 尺寸)。可能,为了兼容微软的实现, 或者因为他们实际使用微软的实现,mingw和 DigitalMars会返回相同的结果。 - Clark S. Cox III cl *******@gmail.com 10是正确的结果。简而言之,微软的snprintf版本已经损坏了(他们的文档甚至声称如果要写入的字符数超过缓冲区,snprintf会返回负值 值 尺寸)。可能,为了兼容微软的实现, 或者因为他们实际使用微软的实现,mingw和 DigitalMars返回相同的结果。 我认为你的后期猜测是正确的。他们称微软提供了 ''C运行时库。'' The C99 standard describes snprintf() in an awkward way, so it''s hard(for me) to assume what the result will be in some situations.1. The "Description" section states:"... Otherwise, output characters beyond the n-1st are discarded ratherthan being written to the array, and a null character is written at theend of the characters actually written into the array."2. The "Returns" section states:"The snprintf function returns the number of characters that would havebeen written had n been sufficiently large, not counting theterminating null character, or a negative value if an encoding erroroccurred. Thus, the null-terminated output has been completely writtenif and only if the returned value is nonnegative and less than n."Consider the following code:#include <stdio.h>int main (void){int r;double d = -10;char str[5];r = snprintf (str, 5, "%f", d);printf ("r=%d str=%s\n", r, (r 0 && r < 5) ? str : "<INVALID>");return 0;}Since the precision is missing, it''s taken as 6, but snprintf() furtherlimits it. My question is, what should be the return value in thiscase:a) 5, "str" contains "-10."b) 5 (number of characters needed for the double to fit, since itdidn''t fit into "str"), "str" contents invalidc) -1 due to an encoding error, "str" contents invalidd) something else that I''ve missedMy assumption would be 5, but it seems to be incorrect. The followingare the results from different systems:gcc 3.3 (Mac OS X): 10gcc 3.4.5 (Windows, mingw): -1BC++ 5.5.1 (Windows): 10MS VC++ 6.0 and 2005 (Windows, _snprintf() used): -1DigitalMars 8.42n (Windows): -1I''d also like to know what an "encoding error" means in snprintf()case. Isn''t it generally related to multibyte/wide characters?--WYCIWYG - what you C is what you get 解决方案The return value should be 10, since that''s how many chars (withoutthe trailing ''\0'') are in "-10.000000", the string you get for anunadorned "%f" with -10. The arry ''str'' will only contain as manyof these 10 characters as fit into the string (including the trai-ling ''\0''), so it would be "-10." in your case. This allows you touse snprintf() to find out how many characters you are going toneed - just call it with 0 as the second argument and it gives youthe strlen() of the string that would result for a fully success-ful call of snprintf(). This number you can then be used to allocateexactly as much memory as needed for the resulting string (and youcan then use the probably slightly faster sprintf();-)Looks as if some of these compilers use a non-compliant libc.Some of the first implementations of sprintf() (before theC99 standard, e.g. the GNU libc 5) did return -1 if theresulting string did not fit into memory allowed for writing.And this old behaviour does not seem to have been correctedin all the implementations you tested.Yes. As far as I can see you will get an "encoding error" if youask snprintf() to print out a wchar_t string using "%ls", butthe string does contain data that are not valid wide characters.Regards, Jens--\ Jens Thoms Toerring ___ [email protected]\__________________________ http://toerring.de10 is the correct result. Put simply, Microsoft''s version of snprintf isbroken (Their documentation even claims that snprintf returns a negativevalue if the number of characters to be written exceeds the buffersize). Likely, either for compatibility with Microsoft''s implementation,or because they actually use Microsoft''s implementation, mingw andDigitalMars return the same result.--Clark S. Cox III cl*******@gmail.com10 is the correct result. Put simply, Microsoft''s version of snprintf isbroken (Their documentation even claims that snprintf returns a negativevalue if the number of characters to be written exceeds the buffersize). Likely, either for compatibility with Microsoft''s implementation,or because they actually use Microsoft''s implementation, mingw andDigitalMars return the same result.I think your latter guess is correct. They call the Microsoft supplied''C runtime library.'' 这篇关于snprintf()返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-05 09:34