Char **使用和打印

时间:2013-01-28 02:52:57

标签: c malloc multidimensional-array double-pointer

在C中,我使用char **来保存一系列字符串。

这是我的代码:

char ** c;
//now to fill c with data ????

//cannot change:
printf ("%*s%s", 0, "", *c);
while (*++w)
    printf (" %s", *c);

我不知道如何用c填充数据。什么是正确的方法?我无法更改3条打印线,因为它们处于外部功能中。

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变量中拥有你的字符或字符串。

您可以使用mallocsizeoffor循环执行此操作。

首先你需要为你的字符串向量分配空间(在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;

显然,你不会像我所示那样显式地执行此操作,但这可以在运行时完成而没有太大问题,只需将用户的字符串存储在缓冲区中,然后将其附加到列表中,希望它不会空间不足(有避免这种情况的技术)。

希望这会有所帮助。