如何在C中创build一个string数组?

我想在C中创build一个string数组。如果我使用这个代码:

char (*a[2])[14]; a[0]="blah"; a[1]="hmm"; 

gcc给我“警告:从不兼容的指针types赋值”。 什么是正确的方法来做到这一点?

编辑:我很好奇,为什么这应该给一个编译器警告,因为如果我做printf(a [1]);,它正确地打印“hmm”。

如果你不想改变string,那么你可以简单地做

 const char *a[2]; a[0] = "blah"; a[1] = "hmm"; 

当你这样做的时候,你将会为const char分配一个两个指针的数组。 这些指针将被设置为静态string"blah""hmm"

如果你希望能够改变实际的string内容,你必须做类似的事情

 char a[2][14]; strcpy(a[0], "blah"); strcpy(a[1], "hmm"); 

这将分配两个连续的数组,每个14个char ,之后静态string的内容将被复制到它们中。

有几种方法可以在C中创build一个string数组。如果所有string的长度相同(或者至less具有相同的最大长度),则只需声明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", ...}; 

这假定初始值设定项中的string的大小和数量与您的数组维度匹配。 在这种情况下,每个string的内容(它本身是一个零终止的char数组)被复制到分配给strs的内存中。 这种方法的问题是内部分裂的可能性; 如果有99个string是5个字符或更less,而1个string是20个字符长,则99个string将至less有15个未使用的字符; 这是浪费空间。

而不是使用char的二维数组,你可以存储一个指向char的指针数组:

 char *strs[NUMBER_OF_STRINGS]; 

请注意,在这种情况下,您只分配内存来保存指向string的指针; string本身的内存必须分配到其他地方(作为静态数组或通过使用malloc()或calloc())。 您可以像使用前面的示例一样使用初始化程序列表:

 char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...}; 

不是复制string常量的内容,而是简单地存储指向它们的指针。 请注意,string常量可能不可写; 您可以重新分配指针,如下所示:

 strs[i] = "bar"; strs[i] = "foo"; 

但是你可能无法改变string的内容; 即

 strs[i] = "bar"; strcpy(strs[i], "foo"); 

可能不被允许。

您可以使用malloc()为每个stringdynamic分配缓冲区并将其复制到该缓冲区:

 strs[i] = malloc(strlen("foo") + 1); strcpy(strs[i], "foo"); 

顺便说一句,

 char (*a[2])[14]; 

声明一个指向14个元素的char数组的指针的2元素数组。

确认! 常量string:

 const char *strings[] = {"one","two","three"}; 

如果我没记错的话。

哦,你想使用strcpy分配,而不是=运算符。 strcpy_s更安全,但在C89和C99标准中都没有。

 char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE]; strcpy(arr[0], "blah"); 

更新: 托马斯说strlcpy是要走的路。

以下是您的一些select:

 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的优点是你可以用string做下面的事情

 a2[0] = "hmm"; a2[1] = "blah"; 

对于a3,您可以执行以下操作:

 a3[0] = &"hmm"; a3[1] = &"blah"; 

对于a1,即使分配string文字,也必须使用strcpy。 原因是a2和a3是指针数组,你可以使它们的元素(比如指针)指向任何存储,而a1是一个“字符数组”的数组,所以每个元素都是一个“拥有”它的数组自己的存储空间(这意味着它在超出范围时会被破坏) – 只能将内容复制到存储空间中。

这也给我们带来了使用a2和a3的缺点 – 因为它们指向静态存储(其中存储了string文本),其内容不能被可靠地改变(即未定义的行为),如果你想分配非string文字到a2或a3的元素 – 您将首先必须dynamic分配足够的内存,然后让它们的元素指向这个内存,然后将字符复制到内存中 – 然后必须确保在完成时释放内存。

Bah – 我已经错过了C ++;)

ps让我知道你是否需要例子。

在ANSI C:

 char* strings[3]; strings[0] = "foo"; strings[1] = "bar"; strings[2] = "baz"; 

或者你可以声明一个结构types,它包含一个字符arry(1个string),他们创build一个结构数组,因此一个milti元素数组

 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 } 

这比任何其他方法的优点之一是,这使您可以直接扫描到string,而不必使用strcpy ;

string文字是const char * s。

而你括号的使用是奇怪的。 你可能是说

 const char *a[2] = {"blah", "hmm"}; 

它声明了一个由两个指向常量字符的指针组成的数组,并初始化它们指向两个硬编码的string常量。

如果string是静态的,你最好用:

 const char *my_array[] = {"eenie","meenie","miney"}; 

虽然不是基本ANSI C的一部分,但您的环境很可能会支持语法。 这些string是不可变的(只读的),因此在许多环境中使用比dynamic构buildstring数组更less的开销。

例如,在小型微控制器项目中,该语法使用程序存储器而不是(通常)更珍贵的RAM存储器。 AVR-C是一个支持这种语法的示例环境,但其他大部分都是如此。

如果你不想跟踪数组中的string数量,并想迭代它们,最后只需添加NULLstring:

 char *strings[]={ "one", "two", "three", NULL }; int i=0; while(strings[i]) { printf("%s\n", strings[i]); //do something i++; }; 

您的代码正在创build一个函数指针数组。 尝试

 char* a[size]; 

要么

 char a[size1][size2]; 

代替。

请参阅wikibooks 数组和指针

 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"); } 

这里试试这个!

我错过了某种更dynamic的string数组,其中string的数量可以根据运行时select而变化,但是否则应该修正string。

我已经结束了像这样编码的代码片段:

 #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拾取指向数组string的指针,并使用_countof函数计算拾取的string数量。 (类似于sizeof(arr) / sizeof(arr[0]) )。

还有额外的Ansi使用A2Tmacros进行Unicode转换,但是对于您的情况可能是可选的。

一个好方法是定义一个你自己的string。

 #include <stdio.h> typedef char string[] int main() { string test = "string"; return 0; } 

这真的很简单。