我正在尝试从文件中分割读入的行,并使用strcpy()
将我找到的数据复制到字符数组中我明白strcpy()
在行尾需要一个空终止字符否则它会出现故障,尽管我也尝试使用确定的缓冲区大小strncpy()
以及strncat()
具有相同的结果。在我的代码片段中,我尝试在令牌末尾添加一个空终止字符。
这是我失败的代码片段:
token = strtok(line, s);
strcpy(update, token);
token = strtok(NULL, s);
token = token + '\0';
strcpy(firstName, token);
token = strtok(NULL, s);
此功能中的第一个strcpy()
调用尚未失败。我第二次调用strcpy()
时每次尝试运行它都会失败。
我的其余代码可以找到here
答案 0 :(得分:3)
复制前需要检查空指针。
token = strtok(line, s);
strcpy(update, token);
token = strtok(NULL, s);
//token = token + '\0';
if(NULL != token)
{
strcpy(firstName, token);
token = strtok(NULL, s);
}
答案 1 :(得分:0)
strtok
返回空指针或指向NUL终止字节序列的指针(即有效的C字符串)。
你的token = token + '\0';
并不是在做你(几乎可以肯定)的想法。由于token
是一个指针(来自strtok
的返回类型),它正在进行指针运算。幸运的是,'\0'
是一种冗长的说法0
的方式(当前的琐事:C中的字符文字类型为int
,而不是类型char
),所以至少它没有改变指针。
检查strtok
返回的值。如果您的第二个strcpy
失败,可能是因为strtok
失败并返回空指针。
也就是说,鉴于您使用单个固定字符串来定义分隔符,您可以使用sscanf
更轻松地(更干净地)完成工作。例如,如果s
包含,.-+
,您可以使用:
sscanf(input, "%1[^,.-+]%*c%9[^,.-+]", update, firstname);
我暂时忽略了对strtok
的第三次调用,因为您永远不会将其返回值复制到目的地(但重复上述模式当然会适用于更多变量,当然)。请注意使用%
和扫描集([^...]
)之间的数字。 总是想要在使用%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
的目标是一个问题,因为它总是附加一个尾随'\0'
来终止字符串。在这种情况下,您只分配了一个字符,因此您只有终结器的空间,而不是任何实际数据。您需要将其扩展为至少两个字符。鉴于您要复制到固定大小的缓冲区,您可能希望在复制之前检查字符串是否适合您的缓冲区,或者使用复制的内容来限制它复制的数据大小(并且始终包含终止符,与strncpy
不同。