【问题标题】:Saving and accessing pointers to strings in C在 C 中保存和访问指向字符串的指针
【发布时间】:2017-10-11 04:19:46
【问题描述】:

假设我从标准输入(一行)得到一个字符串。使用该行,我想从中创建一个字符串数组:

char ** array_of_strings

我希望这个字符串数组是该行的数字。例如,如果行输入是这样的:

"aasd1asdf4j  8  98"

数组看起来像这样:

["1", "4", "8", "98"]

首先,我将如何构建数组?我的想法是使用isdigit() 来检查数字何时开始,并指向那里。然后,当数字完成时,我会将第一个非数字字符的字符值更改为'\0'。我将在我从行输入中获得的整个字符串中继续这个过程。但是,由于 array_of_strings 未初始化,我如何才能在不创建段错误的情况下将这些指针实际添加到我的 array_of_strings 中?

这是否可以在不为 array_of_strings 分配任何额外内存的情况下完成?我觉得它可以,因为 array_of_strings 只是保存指向已经加载到内存中的字符串的指针。

我知道这不是一个代码编写服务,但是否可以提供一些关于我如何构建这样一个东西的例子?这在理论上对我来说是有意义的,但我什至不知道如何开始实施它。我上面提供的描述是我目前最接近的代码。

array_of_strings 创建后,是不是就不能使用数组语法来访问它的值(每个都是char * 类型)?点赞:array_of_strings[0]

【问题讨论】:

  • 如果事先不知道数组大小,可以选择使用realloc。如果您知道数组大小的上限,则可以使用它。如果您可以扫描输入,计算位数(无需提取和存储它们),您可以使用普通的malloc/calloc 而不是realloc
  • @Evert 为什么我必须首先分配额外的内存,考虑到将成为数组的字符串(行)已经存在?
  • 您仍然需要一个(动态分配的)char 指针数组来指向每个子字符串的开头吗?您还如何跟踪每个数字字符串的开头?
  • "我上面提供的描述是我目前拥有的最接近代码的描述。":也许值得尝试使用各种方法将其放入实际代码中。尽管在这里,我怀疑您能否成功:指向 char 指针(又名字符串)的指针只能容纳一 (1) 个字符串;因此需要动态分配。
  • @Evert 我现在明白了。对不起,我不是想和你争论,我只是不知道为什么。

标签: c arrays string pointers segmentation-fault


【解决方案1】:

答案是您需要动态内存分配,因为您必须为每个指针分配空间。例如,如果字符串有 150 个数字,则需要一个包含 150 个指针的数组。但是如果字符串有 100 万个数字,则需要一个包含 100 万个指针的数组,每个指针都指向字符串中的正确位置。

【讨论】:

    【解决方案2】:

    如果你这样做 array_of_strings 实际上包含指向原始字符串中位置的指针,那么你首先需要计算你需要多少指针,不仅如此,你还需要存储每个子字符串的长度,或者使用 strpbrk 每个您需要阅读它的时间。

    另一种方法是使用 realloc,每次您找到一个新的子字符串时,您都会重新分配 (n+1) 个字符指针,然后分配适当的内存大小以将字符串复制到。代码看起来像这样(不完整):

        char ** array_of_strings = NULL;
        int n = 0;
        char example[] = "aasd1asdf4j  8  98";
        char numbers[] = "0123456789";
        for(char* i = strpbrk(example, numbers) ; i != NULL ; i = strpbrk(i,numbers) )
        {
            int sizeOfNumSubstring = strspn(i, numbers);
            if(array_of_strings == NULL)
            {
                array_of_strings = (char**)malloc(sizeof(char*));
                *array_of_strings = (char*)calloc(sizeOfNumSubstring+1, sizeof(char));
            }
            else
            {
                array_of_strings = (char**)realloc(array_of_strings, (n+1)*sizeof(char*));
                *(array_of_strings+n) = (char*)calloc(sizeOfNumSubstring+1, sizeof(char));
            }
    
            strncpy(*(array_of_strings+n), i, sizeOfNumSubstring);
            n++;
            i += sizeOfNumSubstring;
        }
    

    【讨论】:

    • 您应该检查malloc() 等的返回值是否有错误;另外,realloc() 的结果应该先存储在一个临时变量中,因为在发生错误时会返回一个空指针,从而导致内存泄漏和数据丢失。
    • 这只是一个例子,OP当然应该知道应该进行一些检查。
    【解决方案3】:

    如果没有动态分配,就可以创建一个字符串数组。 在下面的代码中,它保存了字符串中出现的每个数字,如果它被一个字符打断,我们转到下一个数组,依此类推

    #define NUM_STRS 10
    #define NUM_CRS  100
    char *nums="0123456789\0"; 
    char *str="aasd1asdf4j  8  98\0";
    char arrstrs[NUM_STRS][NUM_CRS]={0};//array of 200 strings with 200 crs lenght
    int nextString=0;
    int nextChar=0;
    char *pD=str;//pointer to line
    
    while(1)
    {
        if(*pD=='\0')/*break if null cr*/
            break;
        int k=0;
        for (k=0;k<10;k++)
        {
            if(*pD==nums[k])
            {  
                arrstrs[nextString][nextChar]=*pD;
                nextChar++;
                break;
            }
        }
        /*If k is less than 10, continue in this same string */
        if(k==10)/*If it reaches 10 means that it is not a number*/
        { 
            if(nextChar)/*If something was added...*/
            {           
                arrstrs[nextString][nextChar]='\0';/*close buffer*/
                nextString++;/*go to next string*/
                nextChar=0; /*reset to zero for new string*/
            }           
        }
        pD++;/*increment pointer*/
    
    }
    /*testing*/
    for(int u=0;u<NUM_STRS;u++)
        printf("%s\n",arrstrs[u] );
    

    【讨论】:

      猜你喜欢
      • 2011-08-11
      • 2011-04-12
      • 1970-01-01
      • 2021-06-28
      • 2013-02-16
      • 2015-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多