我正在尝试在C中创建一个字符串数组。如果我使用此代码:
char (*a[2])[14];
a[0]="blah";
a[1]="hmm";
gcc给我“警告:从不兼容的指针类型分配”。这样做的正确方法是什么?
编辑:我很好奇为什么这会给编译器警告,因为如果我printf(a[1]);
,它会正确打印“hmm”。
答案 0 :(得分:207)
如果您不想更改字符串,则只需执行
即可const char *a[2];
a[0] = "blah";
a[1] = "hmm";
当你这样做时,你将分配一个指向const char
的两个指针的数组。然后,这些指针将设置为静态字符串"blah"
和"hmm"
的地址。
如果您确实希望能够更改实际的字符串内容,则必须执行类似
的操作char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
这将分配两个连续的14个char
个数组,然后将静态字符串的内容复制到其中。
答案 1 :(得分:161)
有几种方法可以在C中创建字符串数组。如果所有字符串的长度相同(或者至少具有相同的最大长度),则只需声明一个2-d数组的char并赋值必要时:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");
您也可以添加初始值设定项列表:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};
这假定初始化程序中字符串的大小和数量与数组维度相匹配。在这种情况下,每个字符串文字的内容(它本身是一个以零结尾的char数组)被复制到分配给strs的内存中。这种方法的问题是内部碎片化的可能性;如果您有99个字符串,不超过5个字符,但是1个字符串长度为20个字符,则99个字符串将至少包含15个未使用的字符;这是浪费空间。
您可以存储一个指向char的指针数组,而不是使用二维char数组:
char *strs[NUMBER_OF_STRINGS];
请注意,在这种情况下,您只分配了内存来保存指向字符串的指针;字符串本身的内存必须在别处分配(作为静态数组或使用malloc()或calloc())。您可以使用初始化列表,如前面的示例所示:
char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};
不是复制字符串常量的内容,而是简单地存储指针。请注意,字符串常量可能不可写;您可以重新分配指针,如下所示:
strs[i] = "bar";
strs[i] = "foo";
但是你可能无法改变字符串的内容;即,
strs[i] = "bar";
strcpy(strs[i], "foo");
可能不被允许。
您可以使用malloc()为每个字符串动态分配缓冲区并复制到该缓冲区:
strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");
BTW,
char (*a[2])[14];
将a声明为指向14元素char数组的2元素指针数组。
答案 2 :(得分:84)
的Ack!常量字符串:
const char *strings[] = {"one","two","three"};
如果我没记错的话。
哦,你想使用strcpy进行分配,而不是使用=运算符。 strcpy_s更安全,但它既不是C89也不是C99标准。
char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE];
strcpy(arr[0], "blah");
更新: Thomas说strlcpy
是可行的方法。
答案 3 :(得分:12)
以下是您的一些选择:
char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" }; // only since you brought up the syntax -
printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah
a2的优点是您可以使用字符串文字
执行以下操作a2[0] = "hmm";
a2[1] = "blah";
对于a3,您可以执行以下操作:
a3[0] = &"hmm";
a3[1] = &"blah";
对于a1,即使在分配字符串文字时也必须使用strcpy。原因是a2和a3是指针数组,你可以使它们的元素(即指针)指向任何存储,而a1是“字符数组”的数组,所以每个元素都是一个“拥有”它的数组自己的存储(这意味着当它超出范围时会被破坏) - 你只能将东西复制到它的存储中。
这也带来了使用a2和a3的缺点 - 因为它们指向静态存储(存储字符串文字),其内容无法可靠地更改(即未定义的行为),如果要指定非-string文字到a2或a3的元素 - 你首先必须动态分配足够的内存,然后让它们的元素指向这个内存,然后将字符复制到它 - 然后你必须确保释放内存时完成。
Bah - 我已经错过了C ++;)
P.S。如果您需要示例,请告诉我。
答案 4 :(得分:10)
在ANSI C中:
char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
答案 5 :(得分:10)
或者你可以声明一个结构类型,它包含一个字符arry(1个字符串),它们创建一个结构数组,从而创建一个多元素数组
typedef struct name
{
char name[100]; // 100 character array
}name;
main()
{
name yourString[10]; // 10 strings
printf("Enter something\n:);
scanf("%s",yourString[0].name);
scanf("%s",yourString[1].name);
// maybe put a for loop and a few print ststements to simplify code
// this is just for example
}
这比任何其他方法的优点之一是,这允许您直接扫描到字符串而无需使用strcpy
;
答案 6 :(得分:9)
如果您不想跟踪数组中的字符串数并希望迭代它们,只需在最后添加NULL字符串:
char *strings[]={ "one", "two", "three", NULL };
int i=0;
while(strings[i]) {
printf("%s\n", strings[i]);
//do something
i++;
};
答案 7 :(得分:8)
字符串文字是const char *
s。
你对括号的使用很奇怪。你可能意味着
const char *a[2] = {"blah", "hmm"};
声明一个包含两个常量字符指针的数组,并将它们初始化为两个硬编码字符串常量。
答案 8 :(得分:8)
如果字符串是静态的,那么最好用:
const char *my_array[] = {"eenie","meenie","miney"};
虽然不是基本ANSI C的一部分,但您的环境很可能支持语法。这些字符串是不可变的(只读),因此在许多环境中使用比动态构建字符串数组更少的开销。
例如,在小型微控制器项目中,此语法使用程序存储器而不是(通常)更珍贵的RAM内存。 AVR-C是支持这种语法的示例环境,但大多数其他语言也是如此。
答案 9 :(得分:3)
答案 10 :(得分:1)
你好,你可以试试这个:
import MyForm from './MyForm';
<MyForm onSubmit={() => console.log("submit")} loading />
如果你想要的话,在c中使用字符串数组的一个很好的例子
char arr[nb_of_string][max_string_length];
strcpy(arr[0], "word");
答案 11 :(得分:0)
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("\nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("\nEnter name = ");
scanf("%s",&name[i]);
}
}
//printing the data
for(i=0;i<n;i++)
{
for(j=0;j<1;j++)
{
printf("%d\t|\t%s\t|\t%s",rollno[i][j],name[i],sex[i]);
}
printf("\n");
}
在这里试试!!!
答案 12 :(得分:0)
我在某种程度上缺少更多动态字符串数组,其中字符串的数量可能因运行时选择而异,但其他字符串应该是固定的。
我最终编码了这样的代码片段:
#define INIT_STRING_ARRAY(...) \
{ \
char* args[] = __VA_ARGS__; \
ev = args; \
count = _countof(args); \
}
void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
USES_CONVERSION;
char** ev = nullptr;
int count = 0;
if( key.Compare("horizontal_alignment") )
INIT_STRING_ARRAY( { "top", "bottom" } )
if (key.Compare("boolean"))
INIT_STRING_ARRAY( { "yes", "no" } )
if( ev == nullptr )
return;
for( int i = 0; i < count; i++)
item->AddOption(A2T(ev[i]));
item->AllowEdit(FALSE);
}
char** ev
选择指向数组字符串的指针,count使用_countof
函数获取字符串数量。 (类似于sizeof(arr) / sizeof(arr[0])
)。
使用A2T
宏进行unicode转换还有额外的Ansi,但对于你的情况,这可能是可选的。
答案 13 :(得分:-6)
一个好方法是定义一个你自己的字符串。
#include <stdio.h>
typedef char string[]
int main() {
string test = "string";
return 0;
}
真的那么简单。