snprintf() returning inappropriate value

时间:2015-04-29 00:18:11

标签: c++ printf

I've been looking over this piece of code for a while, and I can't seem to find my bug. I think I know how snprintf(dest, n, fmt, src) is supposed to work ( it returns the number of remaining characters in the src buffer after filling the dest buffer with n characters from the fmt string and the src buffer) but it is not doing what I would expect. Instead of returning the number of remaining characters to be copied, it is returning the total characters copied.

The code below:

 40   char header_file_name[200];
 ....
 87   int n_overflow = 0;
 88   n_overflow = snprintf( header_file_name, 200, "%s.h", template_name );
 89   if ( n_overflow > 0 )
 90   {
 91       printf( "That template name is too large; try a smaller template name\n");
 92       printf("n_overflow = %d\n", n_overflow);
 93       printf("header_file_name = %s\n", header_file_name );
 94       printf("length of header_file_name = %d\n", strlen(header_file_name));
 95       printf( "template_name = %s\n", template_name );
 96       printf("length of template_name = %d\n", strlen(template_name));
 97       exit(4);
 98   }
 99   if ( n_overflow < 0 )
100   {
101       printf( "An error occurred while handling your input; file: %s, line:%d\n", __FILE__, __LINE__);
102       exit(1);
103   }

outputs the following:

Compiling template file ABAQUS_Version_5.template
That template name is too large; try a smaller template name
n_overflow = 18
header_file_name = ABAQUS_Version_5.h
length of header_file_name = 18
template_name = ABAQUS_Version_5
length of template_name = 16
*** Error code 4
clearmake: Error: Build script failed for "ABAQUS_Version_5.o"

What makes it so confusing is that my dest (header_file_name) has a length, and even has data in it after the snprintf() call, and my src (template_name) also has a length and is not NULL. I've probably just made some gaff in my code, or I don't really understand snprintf(), and have been starring at it for too long. Any assistance will be greatly appreciated!

1 个答案:

答案 0 :(得分:3)

That's what snprintf is supposed to do.

From man snprintf on an Ubuntu system: (emphasis added)

The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated.

Or, the even simpler wording from Posix:

Upon successful completion, the snprintf() function shall return the number of bytes that would be written to s had n been sufficiently large excluding the terminating null byte.