在C中,我使用char **
来保存一系列字符串。
这是我的代码:
char ** c;
//now to fill c with data ????
//cannot change:
printf ("%*s%s", 0, "", *c);
while (*++w)
printf (" %s", *c);
我不知道如何用c
填充数据。什么是正确的方法?我无法更改3条打印线,因为它们处于外部功能中。
答案 0 :(得分:3)
我认为术语在这里很重要。 char **
根本不“保留”一系列字符串(与C语言中的高级语言中的容器对象不同)。变量c
只是指向字符指针的指针,该字符将成为以空字符结尾的字符串中的第一个字符。
这种思路直接导致了解决方案:如果c是指向字符指针的指针,那意味着我们必须分配一些实际存放字符串数组的内存。
@ DB_Monkey作为评论发布的解决方案试图做到这一点,但不太正确,因为它意味着像c[0] = "cat"
这样的代码将“cat”复制到c[0]
中,但事实并非如此 - 赋值适用于指针,而不适用于字符串。更好的方法是:
int rows = 3;
char **c = calloc (rows,sizeof(char*));
c[0] = "cat";
c[1] = "dog";
c[2] = "mouse";
这也表明没有必要显示每个字符串的显式nul终止。
答案 1 :(得分:1)
你所拥有的是指向char
指针的指针。这意味着你有足够的空间来引用一个可能(更多必须)是另一个指针的变量。在为这些字符保留空间之前,这不允许您在其中保存实际字符。
所以,现在,你需要两步分配内存,这样你就可以在c
变量中拥有你的字符或字符串。
您可以使用malloc,sizeof和for
循环执行此操作。
首先你需要为你的字符串向量分配空间(在C中,它只是字符的向量,所以,实际上,你将为你的字符向量指针向量分配空间):
char **c = malloc(NUMBER_OF_STRINGS * sizeof(char*));
这使得你的c变量指向NUMBER_OF_STRINGS
,它是一个整数,指向char的指针。
现在,您可以为字符串选择最大大小并为其分配所需的所有空间,或者每次需要添加新字符串时都可以这样做:
/*All the space with MAX_STR= maximum string size*/
for(i=0;i<NUMBER_OF_STRINGS;i++){
c[i] = malloc(MAX_STR * sizeof(char));
}
现在,您可以将字符串复制到c[i]
,其中包含MAX_STR
大小的字符串,甚至可以通过char
给出字符串中的实际c[i][j]
你是i字符串中的j字符。
/*Alloc when you have the string*/
while(fgets(buff, BUFFSIZE, stdin) != NULL){ //This is just an example of an input reading from the keyboard
c[i] = malloc(strlen(buff) * sizeof(char));
i++;
}
我使用函数strlen
来获取buff
的大小(buff只是一个字符串)。检查string.h是否有字符串操作函数。
所以我希望这能解决你的问题。还有一件事,在每个malloc之后,你应该检查malloc
是否在你失去进程虚拟内存时没有返回NULL
。
希望这有帮助。
答案 2 :(得分:1)
你的char **实际上是一个数字,它认为该数字是一个有效字符的n地址的数字的地址......
简单地说:
// I am a number that has undefined value, but I pretend to point to a character.
char* myCharPointer;
// the statement above will crash(due to accessing illegal memory), or access arbitrary memory.
char myChar = *myCharPointer;
要使用此指针,必须对其进行初始化。
char* myCharPointer = (char*)malloc(10 * sizeof(char));
现在,您可以像处理数组一样使用此指针,或者根据需要使用指针算法。
请注意,malloc不会将“array”中的所有值都设置为0,默认情况下它们的值是未定义的。
为了做你想做的事,你必须做以下事情:
// I can store 10 "strings"
char** myArrayOfStrings = (char**)malloc(10 * sizeof(char*));
char* str0 = "Hello, world0";
char* str1 = "Hello, World1";
char* str2 = "Hello, World2";
char* str3 = "Hello, world3";
char* str4 = "Hello, world4";
char* str5 = "Hello, world5";
char* str6 = "Hello, world6";
char* str7 = "Hello, world7";
char* str8 = "Hello, world8";
char* str9 = "Hello, world9";
myArrayOfStrings[0] = str0;
myArrayOfStrings[1] = str1;
myArrayOfStrings[2] = str2;
myArrayOfStrings[3] = str3;
myArrayOfStrings[4] = str4;
myArrayOfStrings[5] = str5;
myArrayOfStrings[6] = str6;
myArrayOfStrings[7] = str7;
myArrayOfStrings[8] = str8;
myArrayOfStrings[9] = str9;
// the above is the same as
// *(myArrayOfStrings+9) = str9
你不必拥有相同长度的字符串, 假设str [0..9]实际上是存储这些字符串的第一个字符在内存中的位置的数字,例如
str0 = (char*)&9993039;
str1 = (char*)&9993089;
myArrayOfStrings实际上也是一个存储第一个字符串位置地址的数字 myArrayOfStrings =(char **)&amp; str0;
显然,你不会像我所示那样显式地执行此操作,但这可以在运行时完成而没有太大问题,只需将用户的字符串存储在缓冲区中,然后将其附加到列表中,希望它不会空间不足(有避免这种情况的技术)。
希望这会有所帮助。