7

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

这是我的代码:

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

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

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

4

3 回答 3

7

我认为,术语在这里很重要。根本不“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 终止。

于 2013-01-28T03:11:56.250 回答
4

你的 char** 实际上是一个数字,它认为该数字是一个数字的地址,它是一个有效字符的地址......

简而言之:

// I am a number that has undefined value, but I pretend to point to a character.
char *myCharPointer;
// | The statement below will access arbitrary memory
// |   (which will cause a crash if this memory is not allowed to be accessed).
char myChar = *myCharPointer; 

要使用此指针,您必须对其进行初始化。

char *myCharPointer = (char *)malloc(10 * sizeof(char));

现在,您可以像处理数组一样使用这个指针,或者如果需要,可以使用适当的指针算法。

请注意,malloc 不会将“数组”中的所有值都设置为 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 **)&str0;

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

希望这有帮助。

于 2013-01-28T03:39:40.433 回答
2

你所拥有的是一个指向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,当您用完进程虚拟内存时会发生这种情况。

希望这可以帮助。

于 2013-01-28T03:35:09.053 回答