在C语言中将字符串添加到字符数组中

3
我有一个名为buf的C数组。以下是它的定义:
char buf[1024];
现在,我的当前代码从stdin中获取数据,并使用fgets()函数将其设置到该数组中。但是我希望改用代码来设置它。现在设置buf的行看起来像这样:
fgets(buf, 1024, stdin);
基本上,我想要用"My String"替换stdin。最好的方法是什么?
5个回答

9
请看这里:Cpp reference,寻找 sprintf
sprintf(buf, "My string with args %d", (long) my_double_variable);

编辑2:

如建议的那样,为避免溢出(但这是标准C),您可以使用snprintf


1
查看 sprintf_s 使其更安全,避免缓冲区溢出攻击。 - KLee1
@KLee1:一般来说是很好的建议。然而,考虑到字符串将在代码内部提供,而不是用户提供的缓冲区,缓冲区溢出攻击似乎不太可能发生。 - torak
@KLee1:我在问题中没有看到任何迹象表明OP正在使用具有“sprintf_s”的环境,它似乎不在C99中。 - David Thornley
1
遵循标准和可移植性,避免使用 _s 函数。 - Stephen P
@所有人 抱歉,我是指snprintf。我的错。 - KLee1
显示剩余3条评论

5

snprintf 只是 C99 标准,不是 C89,sprintf_s/strcpy_s 只有在 MSVC 中才有,不是 C89,也不是 C99。

char *mystr="come from stdin or file or ...";
char buf[1024];
...
memset(buf,0,sizeof buf);
strncpy(buf,mystr,(sizeof buf)-1);

或非数组:
#define BUFLEN 512
char *mystr="come from stdin or file or ...";
char *buf;
...
char *buf=calloc(1,BUFLEN);
strncpy(buf,mystr,BUFLEN-1);

它可在所有 ANSI C 环境下使用。

3
strcpy(buf, "My String");

微软的编译器还包括一个名为strcpy_s的函数,它是strcpy的“安全”版本。它确保您不会溢出buf。在这种特定情况下,这可能不是问题,但您应该知道。但请注意,它在任何其他编译器中都不可用,因此无法在需要可移植性的地方使用。

 strcpy_s(buf, sizeof(buf), "My String");

1

有许多变体,其中一些已经被提出,一些未被提出:

...

char input[] = "My String";

strcpy(buf, input);

strncpy(buf, input, sizeof(buf));

sscanf(input, "%s", buf);

sprintf(buf, "%s", input);

memcpy(buf, input, strlen(input));

...

大多数人都不确定/不安全。需要采取什么措施取决于您在代码中真正想要做什么。

敬礼

rbo


-1

冗长但安全:

int copy_size = sizeof( buf ) - 1 < strlen( MyString ) ? sizeof( buf ) - 1 : strlen( MyString );
memset( buf, 0, copy_size + 1 );
memcpy( buf, MyString, copy_size );

这太糟糕了。为什么要将如此多的内存清零,只是为了用memcpy覆盖它?看看BSD的strlcpy。 - user410344

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接