将 strcpy() 与 strtok 一起使用

using strcpy() with strtok

我正在尝试拆分从文件中读入的行,然后使用 strcpy() 将我找到的数据复制到字符数组中 我知道 strcpy() 需要在末尾有一个空终止字符该行否则它将出现段错误,尽管我也尝试使用确定的缓冲区大小 strncpy() 以及 strncat() 并获得相同的结果。在我的代码片段中,我尝试在标记的末尾简单地添加一个空终止字符。

这是我失败的代码片段:

    token = strtok(line, s);
    strcpy(update, token);
    token = strtok(NULL, s);
    token = token + '[=10=]';
    strcpy(firstName, token);
    token = strtok(NULL, s);

此函数中的第一个 strcpy() 调用尚未失败。我第二次调用 strcpy() 每次尝试 运行 它都会失败。

我的其余代码可以找到here

strtok returns 要么是空指针,要么是指向以 NUL 结尾的字节序列(即有效的 C 字符串)的指针。

您的 token = token + '[=13=]'; 没有按照您(几乎可以肯定)的想法行事。由于 token 是一个指针(即来自 strtok 的 return 类型),它正在进行指针运算。幸运的是,'[=16=]'0 的一种冗长的表达方式(暂时的琐事:C 中的字符文字具有类型 int,而不是类型 char),所以至少它没有改变指针。

检查 return 由 strtok 编辑的值。如果您的第二个 strcpy 失败,可能是因为 strtok 失败并且 return 空指针。

也就是说,如果您使用单个固定字符串来定义分隔符,那么使用 sscanf 可能会更轻松(也更干净)地完成这项工作。例如,如果 s 包含 ,.-+,您可以使用:

sscanf(input, "%1[^,.-+]%*c%9[^,.-+]", update, firstname);

我暂时忽略了对 strtok 的第三次调用,因为您永远不会从其 return 值复制到目的地(但重复上述模式将适用于更多变量,当然)。注意 % 和扫描集 ([^...]) 之间数字的使用。在使用 %s 或 %[...]. The size you specify should always be one smaller than the buffer into which you're having them write (because they always append a trailing'\0'`).

时,您总是 想要指定缓冲区的大小

如果 s 实际上是您从外部来源读取的字符串(或按该顺序的内容,因此您不能轻易地将其内容放入字符串文字中),您可以合成您的如果需要,在 运行 时间格式化字符串:

char template[] = "%%[^%s]%%*c%%[^%s]";
char format[512];

sprintf(format, template, s, s);
sscanf(input, format, update, firstname);

[虽然格式字符串通常是文字,但这不是必需的。]

编辑:我不认为您最初链接了代码,但它至少揭示了一个问题:char update[1];。使用它作为 strcpy 的目标是一个问题,因为它总是附加一个尾随 '[=16=]' 来终止字符串。在这种情况下,您只分配了一个字符,因此您只有终止符的空间,而不是任何实际数据。您需要将其扩展到至少两个字符。鉴于您正在复制到固定大小的缓冲区,您可能想要在复制之前检查字符串是否适合您的缓冲区,或者使用一些限制复制数据大小的东西来复制(并且仍然总是包括一个终结符,不像 strncpy).

复制前需要检查空指针。

token = strtok(line, s);
strcpy(update, token);
token = strtok(NULL, s);
//token = token + '[=10=]';
if(NULL != token)
{
    strcpy(firstName, token);
    token = strtok(NULL, s);
}