如何在C中创建字符串数组?

我试图在c中创建一个字符串数组,如果我使用以下代码:

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

GCC给我“警告:来自不兼容的指针类型的赋值”。正确的做法是什么?

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

1267762 次浏览

Ack !常量字符串:

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

如果我没记错的话。

哦,你想要使用拷贝字符串来赋值,而不是=运算符。strcpy_s更安全,但它既不在C89标准也不在C99标准。

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

更新: 托马斯。strlcpy是可行的。

字符串字面量是const char *s。

你用圆括号也很奇怪。你的意思可能是

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

它声明了一个包含两个指向常量字符的指针的数组,并将它们初始化为指向两个硬编码的字符串常量。

在ANSI C中:

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

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

char* a[size];

char a[size1][size2];

代替。

参见wikibooks到数组指针

如果您不想更改字符串,那么您可以简单地这样做

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个__abc0,之后静态字符串的内容将被复制到其中。

以下是你的一些选择:

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()(最好是strncpy())。原因是a2a3是指针数组,你可以让它们的元素(即指针)指向任何存储,而a1是一个“字符数组”的数组,因此每个元素都是一个“拥有”自己的存储的数组(这意味着当它超出作用域时就会被销毁)——你只能将东西复制到它的存储中。

这也给我们带来了使用a2a3的缺点——因为它们指向静态存储(字符串字面值存储的地方),其中的内容不能可靠地更改(即未定义的行为),如果你想将非字符串字面值分配给a2a3的元素——你首先必须动态分配足够的内存,然后让它们的元素指向这个内存,然后将字符复制到其中-然后你必须确保在完成时释放内存。

呸——我已经开始想念c++了;)

附注:如果你需要例子,请告诉我。

在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个字符或更少的字符串,但有一个20个字符长的字符串,99个字符串将至少有15个未使用的字符;那是浪费空间。

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

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

顺便说一句,

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

将a声明为指向14元素char数组的指针的2元素数组。

或者你可以声明一个结构类型,它包含一个字符数组(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;

一个好方法是自己定义一个字符串。

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

就是这么简单。

如果字符串是静态的,你最好使用:

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

虽然不是基本的ANSI C的一部分,但您的环境很可能支持该语法。这些字符串是不可变的(只读),因此在许多环境中使用的开销比动态构建字符串数组要少。

例如,在小型微控制器项目中,这种语法使用程序内存,而不是(通常)更宝贵的ram内存。AVR-C是一个支持这种语法的示例环境,但大多数其他环境也是如此。

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

来试试这个!!

如果你不想跟踪数组中字符串的数量,并且想要遍历它们,只需在最后添加NULL字符串:

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


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

我在某种程度上缺少了更动态的字符串数组,其中字符串的数量可以根据运行时的选择而变化,但字符串应该是固定的。

我最后的代码片段是这样的:

#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]))。

还有额外的Ansi到unicode转换使用A2T宏,但这可能是可选的情况。

你好,你可以试试这个:

 char arr[nb_of_string][max_string_length];
strcpy(arr[0], "word");

这是一个很好的例子,在c语言中使用字符串数组

#include <stdio.h>
#include <string.h>




int main(int argc, char *argv[]){


int i, j, k;


// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];


char temp[100];
char word[100];


for (i = 0; i < 3; i++){
printf("type word %d : ",i+1);
scanf("%s", word);
strcpy(array[i], word);
}


for (k=0; k<3-1; k++){
for (i=0; i<3-1; i++)
{
for (j=0; j<strlen(array[i]); j++)
{
// if a letter ascii code is bigger we swap values
if (array[i][j] > array[i+1][j])
{
strcpy(temp, array[i+1]);
strcpy(array[i+1], array[i]);
strcpy(array[i], temp);


j = 999;
}


// if a letter ascii code is smaller we stop
if (array[i][j] < array[i+1][j])
{
j = 999;
}


}
}
}


for (i=0; i<3; i++)
{
printf("%s\n",array[i]);
}


return 0;
}

每个元素都是指向其第一个字符的指针

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