对于做字符串连接,我一直在做基础strcpy,strncpy字符*缓冲区.然后我了解了snprintf和朋友们.
我应该坚持我的strcpy,strcpy+ \0终结?或者我应该snprintf在将来使用?
在大多数情况下,我怀疑使用strncpy和snprintf可测量之间的区别.
如果涉及任何格式化,我倾向于只坚持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会更强大.如果您只想连接,请使用strncpy(不要使用strcpy),因为它更有效.
正如其他人已经指出的那样:不要使用 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。