如何为C中的字符串数组赋值?
Posted
技术标签:
【中文标题】如何为C中的字符串数组赋值?【英文标题】:How do I assign a value to an array of strings in C? 【发布时间】:2021-09-11 06:43:12 【问题描述】:所以我使用malloc()
创建了一个指针数组。我最终想要一个字符串数组。我将如何将字符串值分配给这些 malloced 指针之一?
例如,如果我做了以下事情:
char ** elements= malloc(N* sizeof(char*));
并循环前一个数组以分配单个指针,如下所示:
elements[i] = malloc((50) * sizeof(char));
【问题讨论】:
此代码将为每个字符串准确分配 50 个字节。你知道你所有的字符串都会比这短吗? 对于此代码,您可能希望使用strcpy(elements[i], somestring)
-- 但是,您必须小心确保每个复制的字符串 somestring
的长度小于 50 个字符。
我明白了,字符串实际上少于 50 个字符,非常感谢!
有一个非标准但广泛可用的函数strdup
,请查看。您也可以实现自己的版本。
C 没有字符串值。只有字符和指针。所以你必须弄清楚“为字符串数组赋值”在实际 C 语言(字符和指针)中的含义。
【参考方案1】:
使用#include <string.h>
包含字符串函数。
比使用 strncpy
函数为 char 数组赋值。要将字符串复制到elements[i]
,请使用:
strncpy(elements[i], "Hello, world!", 49)
您可以将另一个char
数组指针作为第二个参数。请注意,为避免擦除字符串末尾的空字节,请从实际字符串数组长度中减去 1
以保留 '\0'
的最后一个字节。此外,最好使用calloc(50, sizeof(char))
来分配字符串,因为calloc
还会用空字节填充它们。或者,至少,在迭代时添加这一行(将最后一个字节设置为零以使字符串以空值结尾):
elements[i][49] = '\0';
【讨论】:
【参考方案2】:使用当前标准 C,您可以:
#include <stdlib.h>
#include <string.h>
size_t size = strlen(some_string) + 1; // +1 for null term
elements[i] = malloc(size);
memcpy(elements[i], some_string, size);
...
free(elements[i]);
随着即将推出的“C2x”标准(仍处于草案阶段),strdup
可能会被添加到该语言中。尽管它已经作为 POSIX 支持的非标准扩展广泛使用。示例:
#include <string.h>
elements[i] = strdup(some_strings[i]);
...
free(elements[i]);
【讨论】:
【参考方案3】:我们可以使用strncpy()
和类似的函数将某些内容复制到字符串中,例如memcpy()
或使用我们自己的函数。
我建议使用strncpy()
,因为它可以防止溢出,因为它会复制一个直到指定的长度。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char BYTE;
enum
NumStrings = 50,
MaxStrLen = 50
;
int main(void)
char **StrList = malloc(NumStrings * sizeof(char *));
if (StrList == NULL)
perror("malloc");
exit(1);
for (BYTE i = 0; i < NumStrings; i++)
StrList[i] = malloc(MaxStrLen);
if (StrList[i] == NULL)
perror("malloc");
exit(1);
// Here we copy something into the string for example
strncpy(StrList[i], "test", 50);
StrList[i][49] = '\0';
// Print string here to show it's copied
printf("%s ", StrList[i]);
putchar('\n');
for (BYTE i = 0; i < NumStrings; i++)
free(StrList[i]);
free(StrList);
exit(0);
【讨论】:
不幸的是,strncpy
所解决的问题与它所解决的问题一样多,因为如果源字符串恰好是 N 个字符长,则复制的字符串将不会正确地以空值结尾。真正安全的选择是strlcpy
,尽管它不是标准的。
“我推荐使用 strncpy(),因为它可以防止溢出” 这是完全错误的。请学习Is strcpy dangerous and what should be used instead?
@SteveSummit strcpy_s
已正式标准化,但实际上很少有编译器实现 C11 边界检查库。以上是关于如何为C中的字符串数组赋值?的主要内容,如果未能解决你的问题,请参考以下文章