c中的snprintf与strcpy(等)

mon*_*ing 6 c string printf

对于做字符串连接,我一直在做基础strcpy,strncpy字符*缓冲区.然后我了解了snprintf和朋友们.

我应该坚持我的strcpy,strcpy+ \0终结?或者我应该snprintf在将来使用?

Joh*_*ter 7

在大多数情况下,我怀疑使用strncpysnprintf可测量之间的区别.

如果涉及任何格式化,我倾向于只坚持snprintf而不是混合strncpy.

我发现这有助于代码清晰度,并且意味着您可以使用以下习惯来跟踪您在缓冲区中的位置(从而避免创建Shlemiel the Painter算法):

char sBuffer[iBufferSize];
char* pCursor = sBuffer;

pCursor += snprintf(pCursor, sizeof(sBuffer) - (pCursor - sBuffer),  "some stuff\n");

for(int i = 0; i < 10; i++)
{
   pCursor += snprintf(pCursor, sizeof(sBuffer) - (pCursor - sBuffer),  " iter %d\n", i);
}

pCursor += snprintf(pCursor, sizeof(sBuffer) - (pCursor - sBuffer),  "into a string\n");
Run Code Online (Sandbox Code Playgroud)

  • 如果你只使用一次"snprintf"调用就更清楚了.并且要注意,如果缓冲区不够大,`snprintf`将返回必要的缓冲区大小(或失败时的负数),因此增加像这样的'pCursor`可能是危险的. (3认同)

yas*_*sin 6

如果要格式化字符串,snprintf会更强大.如果您只想连接,请使用strncpy(不要使用strcpy),因为它更有效.

  • 引自Linux man on strncpy:“警告:如果src的前n个字节中没有空字节,则放置在dest中的字符串将不会以空终止。” 所以这不仅仅是效率的问题。 (2认同)

Tho*_*efe 6

正如其他人已经指出的那样:不要使用 strncpy。

  • strncpy 在截断的情况下不会零终止。
  • 如果字符串比缓冲区短,strncpy 将对整个缓冲区进行零填充。如果缓冲区很大,这可能会导致性能下降。

snprintf 将(在 POSIX 平台上)零终止。在 Windows 上,只有 _snprintf,它不会以零终止,所以要考虑到这一点。

注意:当使用 snprintf 时,使用这种形式:

snprintf(buffer, sizeof(buffer), "%s", string);
Run Code Online (Sandbox Code Playgroud)

代替

snprintf(buffer, sizeof(buffer), string);
Run Code Online (Sandbox Code Playgroud)

后者是不安全的,并且 - 如果字符串取决于用户输入 - 可能导致堆栈粉碎等。


小智 5

我认为 strncpy 和 snprintf 之间还有另一个区别。

想一想:

const int N=1000000;
char arr[N];
strncpy(arr, "abce", N);
Run Code Online (Sandbox Code Playgroud)

通常,strncpy 会将目标缓冲区的其余部分设置为“\0”。这将花费大量的 CPU 时间。当你调用 snprintf 时,

snprintf(a, N, "%s", "abce");
Run Code Online (Sandbox Code Playgroud)

它将保持缓冲区不变。

我不知道为什么 strncpy 会这样做,但在这种情况下,我会选择 snprintf 而不是 strncpy。