snprintf()返回值 [英] snprintf() return value

查看:124
本文介绍了snprintf()返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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>解决方案

matevzb< ma ***** @ gmail.comwrote:


C99标准描述了snprintf ()以一种尴尬的方式,所以很难

(对我来说)假设在某些情况下结果会是什么。

1.描述 ;部分状态:

" ...否则,超出n-1的输出字符将被丢弃而不是写入数组,并且写入空字符

实际写入数组的字符的结尾。

2.返回部分状态:

" snprintf函数返回的字符数已经写入了足够大的
,不计算

终止空字符,如果发生编码错误

,则返回负值。因此,当且仅当返回值是非负且小于n时,以空值终止的输出已完全写入



请考虑以下代码:

#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>");


返回0;

}

由于缺少精度,它是'取为6,但snprintf()进一步

限制它。我的问题是,这个

案例的回报值应该是多少:

a)5,str包含-10。

b)5(双精度所需的字符数,因为它是
不适合str) ,str内容无效

c)-1由于编码错误,str内容无效

d)其他我错过的东西



返回值应为10,因为那是多少个字符(没有

尾随的''\ 0'')在-10.000000中,你得到的字符串为

unadorned"%f"用-10。 arry''str''只包含这10个字符中的多个

符合字符串(包括tra $

ling''\ 0''' ),所以它将是-10。在你的情况下。这允许你使用snprintf()来找出你需要多少个字符来支持
需要的东西 - 只需用0作为第二个参数来调用它,它就会给你

字符串的strlen()将导致snprintf()完全成功 -

ful调用。这个数字然后可以用来为结果字符串分配

完全相同的内存(然后你就可以使用可能稍微快一点的sprintf(); - )


我的假设是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



看起来好像其中一些编译器使用了不兼容的libc。

一些sprintf()的第一个实现(在

C99标准之前,例如GNU libc 5)确实返回-1,如果

结果字符串不适合内存允许写作。

在您测试的所有实现中,这种旧行为似乎没有得到纠正



我也想知道什么是编码错误。表示在snprintf()

的情况下。它通常不与多字节/宽字符有关吗?



是的。据我所知,你会得到一个编码错误。如果你是
请求snprintf()使用%ls打印出一个wchar_t字符串,但

该字符串确实包含无效宽字符的数据。 />

问候,Jens

-

\ Jens Thoms Toerring ___ jt@toerring.de

\ __________________________ http:// toerring .de


matevzb写道:


C99标准描述了一个尴尬的snprintf()因此,很难

(对我来说)假设在某些情况下会产生什么结果。

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



10是正确的结果。简而言之,微软的snprintf版本已经损坏了(他们的文档甚至声称如果要写入的字符数超过缓冲区,snprintf会返回负值



尺寸)。可能,为了兼容微软的实现,

或者因为他们实际使用微软的实现,mingw和

DigitalMars会返回相同的结果。


-

Clark S. Cox III
cl *******@gmail.com




Clark S. Cox III写道:
< blockquote class =post_quotes>
matevzb写道:


C99标准以尴尬的方式描述了snprintf(),所以它很难

(对我来说)假设在某些情况下结果会是什么。

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



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 rather
than being written to the array, and a null character is written at the
end of the characters actually written into the array."
2. The "Returns" section states:
"The snprintf function returns the number of characters that would have
been written had n been sufficiently large, not counting the
terminating null character, or a negative value if an encoding error
occurred. Thus, the null-terminated output has been completely written
if 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() further
limits it. My question is, what should be the return value in this
case:
a) 5, "str" contains "-10."
b) 5 (number of characters needed for the double to fit, since it
didn''t fit into "str"), "str" contents invalid
c) -1 due to an encoding error, "str" contents invalid
d) something else that I''ve missed

My assumption would be 5, but it seems to be incorrect. The following
are the results from different systems:
gcc 3.3 (Mac OS X): 10
gcc 3.4.5 (Windows, mingw): -1
BC++ 5.5.1 (Windows): 10
MS VC++ 6.0 and 2005 (Windows, _snprintf() used): -1
DigitalMars 8.42n (Windows): -1
I''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

解决方案

matevzb <ma*****@gmail.comwrote:

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 rather
than being written to the array, and a null character is written at the
end of the characters actually written into the array."
2. The "Returns" section states:
"The snprintf function returns the number of characters that would have
been written had n been sufficiently large, not counting the
terminating null character, or a negative value if an encoding error
occurred. Thus, the null-terminated output has been completely written
if 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() further
limits it. My question is, what should be the return value in this
case:
a) 5, "str" contains "-10."
b) 5 (number of characters needed for the double to fit, since it
didn''t fit into "str"), "str" contents invalid
c) -1 due to an encoding error, "str" contents invalid
d) something else that I''ve missed

The return value should be 10, since that''s how many chars (without
the trailing ''\0'') are in "-10.000000", the string you get for an
unadorned "%f" with -10. The arry ''str'' will only contain as many
of these 10 characters as fit into the string (including the trai-
ling ''\0''), so it would be "-10." in your case. This allows you to
use snprintf() to find out how many characters you are going to
need - just call it with 0 as the second argument and it gives you
the strlen() of the string that would result for a fully success-
ful call of snprintf(). This number you can then be used to allocate
exactly as much memory as needed for the resulting string (and you
can then use the probably slightly faster sprintf();-)

My assumption would be 5, but it seems to be incorrect. The following
are the results from different systems:
gcc 3.3 (Mac OS X): 10
gcc 3.4.5 (Windows, mingw): -1
BC++ 5.5.1 (Windows): 10
MS VC++ 6.0 and 2005 (Windows, _snprintf() used): -1
DigitalMars 8.42n (Windows): -1

Looks as if some of these compilers use a non-compliant libc.
Some of the first implementations of sprintf() (before the
C99 standard, e.g. the GNU libc 5) did return -1 if the
resulting string did not fit into memory allowed for writing.
And this old behaviour does not seem to have been corrected
in all the implementations you tested.

I''d also like to know what an "encoding error" means in snprintf()
case. Isn''t it generally related to multibyte/wide characters?

Yes. As far as I can see you will get an "encoding error" if you
ask snprintf() to print out a wchar_t string using "%ls", but
the string does contain data that are not valid wide characters.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de


matevzb wrote:

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 rather
than being written to the array, and a null character is written at the
end of the characters actually written into the array."
2. The "Returns" section states:
"The snprintf function returns the number of characters that would have
been written had n been sufficiently large, not counting the
terminating null character, or a negative value if an encoding error
occurred. Thus, the null-terminated output has been completely written
if 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() further
limits it. My question is, what should be the return value in this
case:
a) 5, "str" contains "-10."
b) 5 (number of characters needed for the double to fit, since it
didn''t fit into "str"), "str" contents invalid
c) -1 due to an encoding error, "str" contents invalid
d) something else that I''ve missed

My assumption would be 5, but it seems to be incorrect. The following
are the results from different systems:
gcc 3.3 (Mac OS X): 10
gcc 3.4.5 (Windows, mingw): -1
BC++ 5.5.1 (Windows): 10
MS VC++ 6.0 and 2005 (Windows, _snprintf() used): -1
DigitalMars 8.42n (Windows): -1

10 is the correct result. Put simply, Microsoft''s version of snprintf is
broken (Their documentation even claims that snprintf returns a negative
value if the number of characters to be written exceeds the buffer
size). Likely, either for compatibility with Microsoft''s implementation,
or because they actually use Microsoft''s implementation, mingw and
DigitalMars return the same result.

--
Clark S. Cox III
cl*******@gmail.com



Clark S. Cox III wrote:

matevzb wrote:

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 rather
than being written to the array, and a null character is written at the
end of the characters actually written into the array."
2. The "Returns" section states:
"The snprintf function returns the number of characters that would have
been written had n been sufficiently large, not counting the
terminating null character, or a negative value if an encoding error
occurred. Thus, the null-terminated output has been completely written
if 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() further
limits it. My question is, what should be the return value in this
case:
a) 5, "str" contains "-10."
b) 5 (number of characters needed for the double to fit, since it
didn''t fit into "str"), "str" contents invalid
c) -1 due to an encoding error, "str" contents invalid
d) something else that I''ve missed

My assumption would be 5, but it seems to be incorrect. The following
are the results from different systems:
gcc 3.3 (Mac OS X): 10
gcc 3.4.5 (Windows, mingw): -1
BC++ 5.5.1 (Windows): 10
MS VC++ 6.0 and 2005 (Windows, _snprintf() used): -1
DigitalMars 8.42n (Windows): -1


10 is the correct result. Put simply, Microsoft''s version of snprintf is
broken (Their documentation even claims that snprintf returns a negative
value if the number of characters to be written exceeds the buffer
size). Likely, either for compatibility with Microsoft''s implementation,
or because they actually use Microsoft''s implementation, mingw and
DigitalMars return the same result.

I think your latter guess is correct. They call the Microsoft supplied
''C runtime library.''


这篇关于snprintf()返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆