使用 strncpy 复制字符串时遇到异常
encountering exception when copying string using strncpy
我有一个字符串,我正在通过查找特定单词来迭代该字符串,该单词恰好位于两个空格之间。
例如:
// where the word that I'm looking for is /docs/index.html
const char* c = "GET /docs/index.html HTTP/1.1\r\n";
我找到的词如下;
const char* wbeg = strchr(c, ' ') + 1; // points to '/'
const char* wend = strchr(wbeg, ' ') -1; // points to 'l'
如果我想将该词存储到另一个位置,这是我使用 strncpy
实现的
char word[256];
strncpy(word, wbeg, wend - wbeg);
我收到以下错误
Exception thrown at 0x00007FFAAE8C4A74 (ucrtbased.dll) in
ConsoleApplication1.exe: 0xC0000005: Access violation writing location
0x0000000000000000.
strncpy
是一个蹩脚的功能。如果源长于计数参数,它不会正确终止字符串:
char s[] = "AAAAA";
strncpy(s, "BB", 2);
// s is now "BBAAA", not "BB"
您需要在复制后显式终止字符串。
char word[SIZE];
ptrdiff_t count = wend - wbeg + 1;
if(count < SIZE) {
memcpy(word, wbeg, count); // might as well use memcpy
word[count] = '[=11=]';
}
else // handle error
如果您在 post 中显示的要点是 运行 简单的 main()
程序,...
int main()
{
const char* c = "GET /docs/index.html HTTP/1.1\r\n";
const char* wbeg = strchr(c, ' ') + 1; // points to '/'
const char* wend = strchr(wbeg, ' ') -1; // points to 'l'
char word[256];
strncpy(word, wbeg, wend - wbeg);
printf("%s", word);
return 0;
}
...在我的环境中没有发现任何故障。因此,除了 post 剩余的相关代码之外,唯一的建议都是围绕确保您没有调用 UB.
1) 在您的声明中:
strncpy(word, wbeg, wend - wbeg);
`wend - wbeg` is == 15
而 /docs/index.html
是 16 个字符长。
将您的声明更改为:
strncpy(word, wbeg, (wend - wbeg)+1);
2) 从初始化变量开始:
char word[SIZE] = ""
3) strncpy
不为 NULL 终止。如果您要复制到的目标在使用前未初始化,或者您在使用后未明确终止,则可能会出现 UB。
示例:
char target[]; //contents of target are not guaranteed
char source[]="abcdefghijklmnopqrstuv";
strncpy(target, source, 3);
有可能得到如下结果:
|a|b|c|?|?|?|?|?|?|?|?|?|?|?|?|?|...
在哪里?可以是任何东西。
如果你想保证一个ASCII NUL字节在被复制字节的末尾,你可以使用下面的:
strncpy (target, source, 3);
target[3] = 0;
|a|b|c|[=16=]|?|?|?|?|?|?|?|?|?|?|?|?|...
4) 如果复制发生在重叠的两个对象之间,则行为未定义。确保在 strncpy()
中使用它们的结果之前检查 strchr()
函数的结果
我有一个字符串,我正在通过查找特定单词来迭代该字符串,该单词恰好位于两个空格之间。
例如:
// where the word that I'm looking for is /docs/index.html
const char* c = "GET /docs/index.html HTTP/1.1\r\n";
我找到的词如下;
const char* wbeg = strchr(c, ' ') + 1; // points to '/'
const char* wend = strchr(wbeg, ' ') -1; // points to 'l'
如果我想将该词存储到另一个位置,这是我使用 strncpy
char word[256];
strncpy(word, wbeg, wend - wbeg);
我收到以下错误
Exception thrown at 0x00007FFAAE8C4A74 (ucrtbased.dll) in ConsoleApplication1.exe: 0xC0000005: Access violation writing location 0x0000000000000000.
strncpy
是一个蹩脚的功能。如果源长于计数参数,它不会正确终止字符串:
char s[] = "AAAAA";
strncpy(s, "BB", 2);
// s is now "BBAAA", not "BB"
您需要在复制后显式终止字符串。
char word[SIZE];
ptrdiff_t count = wend - wbeg + 1;
if(count < SIZE) {
memcpy(word, wbeg, count); // might as well use memcpy
word[count] = '[=11=]';
}
else // handle error
如果您在 post 中显示的要点是 运行 简单的 main()
程序,...
int main()
{
const char* c = "GET /docs/index.html HTTP/1.1\r\n";
const char* wbeg = strchr(c, ' ') + 1; // points to '/'
const char* wend = strchr(wbeg, ' ') -1; // points to 'l'
char word[256];
strncpy(word, wbeg, wend - wbeg);
printf("%s", word);
return 0;
}
...在我的环境中没有发现任何故障。因此,除了 post 剩余的相关代码之外,唯一的建议都是围绕确保您没有调用 UB.
1) 在您的声明中:
strncpy(word, wbeg, wend - wbeg);
`wend - wbeg` is == 15
而 /docs/index.html
是 16 个字符长。
将您的声明更改为:
strncpy(word, wbeg, (wend - wbeg)+1);
2) 从初始化变量开始:
char word[SIZE] = ""
3) strncpy
不为 NULL 终止。如果您要复制到的目标在使用前未初始化,或者您在使用后未明确终止,则可能会出现 UB。
示例:
char target[]; //contents of target are not guaranteed
char source[]="abcdefghijklmnopqrstuv";
strncpy(target, source, 3);
有可能得到如下结果:
|a|b|c|?|?|?|?|?|?|?|?|?|?|?|?|?|...
在哪里?可以是任何东西。
如果你想保证一个ASCII NUL字节在被复制字节的末尾,你可以使用下面的:
strncpy (target, source, 3);
target[3] = 0;
|a|b|c|[=16=]|?|?|?|?|?|?|?|?|?|?|?|?|...
4) 如果复制发生在重叠的两个对象之间,则行为未定义。确保在 strncpy()
strchr()
函数的结果