要正确解决这个问题,您一定不能忽视您正在处理大小有限的 C 数组这一事实。副本不仅必须按要求在换行处停止,而且必须确保目标数组正确地为空终止,并且它没有溢出。
为此,最好编写一个函数,例如:
#include <string.h>
/* Copy src to dst, until the point that a character from the bag set
* is encountered in src.(That character is not included in the copy.
* Ensures that dst is null terminated, unless dstsize is zero.
* dstsize gives the size of the dst.
* Returns the number of characters required to perform a complete copy;
* if this exceeds dstsize, then the copy was truncated.
*/
size_t copyspan(char *dst, size_t dstsize, const char *src, const char *bag)
{
size_t ideal_length = strcspn(src, bag); /* how many chars to copy */
size_t limited_length = (ideal_length < dstsize) ? ideal_length : dstsize - 1;
if (dstsize > 0) {
memcpy(dst, src, limited_length);
dst[limited_length] = 0;
}
return ideal_length + 1;
}
有了这个函数,我们现在可以做:
if (copyspan(str1, str2, "\n") > sizeof str1) {
/* oops, truncated: handle this somehow */
}
当然,还有fgets可能已经截断了原始数据的问题。
只处理通常由fgets 返回的尾随换行符(除非是溢出的行或未被换行符终止的文件)通常是这样完成的:
{
char line[128];
/*...*/
if (fgets(line, sizeof line, file)) {
char *pnl = strchr(line, '\n'); /* obtain pointer to first newline */
if (pnl != 0) /* if found, overwrite it with null */
*pnl = 0;
}
/*...*/
}
如果你在很多地方都在做这种行读,当然最好做一个包装器而不是重复这个逻辑。