首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >指向2D指针的2D指针

指向2D指针的2D指针
EN

Stack Overflow用户
提问于 2014-09-11 20:46:06
回答 2查看 111关注 0票数 2

我忘了大部分C,所以如果这是个愚蠢的问题,请原谅我。因为我需要把一串单词分成单独的单词。

代码语言:javascript
运行
复制
#include "argsInfo.h"
#include <stdlib.h>

/* Parses string argument which contains words
 * separated by whitespace.  It returns an
 * argsInfo data structure which contains an
 * array of the parsed words and the number
 * of words in the array.
 */

argsInfo getArgsInfo(char * string) {
    argsInfo info;
    char ** temp;
    int nWords=1;
    int i=0;
    int j,k;
    //Test if the the input string is empty
    if (string[0] == '\0'){
        nWords=0;
    }else{
        //First I need to check how long the input String is, as-well as cout how many words are in the string.
        while (string[i] != '\0'){
            if (string[i] == ' '){
               nWords++;
            }
            i++;
        }
    }
    //This allocates enough memory for each word.
    temp = (char**) malloc(nWords*sizeof(char*));

    for (j=0;j<nWords;j++){
        temp[j] = (char*) malloc(i*sizeof(char));
    }
    j=0;
    k=0;
    // If I encounter a white space, it signifies a new word, and I need to move it to the next element
    while (j < i){
        if (string[j] == ' '){
            k++;
        }
        temp[k][j] = string[j];
        j++;
    }
    info.argc = nWords;
    info.argv = temp;
    return info;
}

最后一排。我觉得问题就在那里。info.argv = temp;

这就是这个结构的样子:

代码语言:javascript
运行
复制
 typedef struct {
    int argc;
    char ** argv;
 } argsInfo;

输入和输出示例:

输入:"ax bcd efghij“

输出: ax

如果删除k++行,输出为:

同样,如果我输入一个bc.c,在运行数组时,只有'a‘才会出现。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-11 21:14:40

首先,这部分效率很低,但效果很好:

代码语言:javascript
运行
复制
for (j=0;j<nWords;j++){
    temp[j] = (char*) malloc(i*sizeof(char));
}

您使用的是i的值,它将等于原始输入字符串中的字符总数。这意味着,对于每个单独的单词,您都有足够的空间存储原来的句子,这是浪费空间。例如,当你在计算单词时,你也可以记住到目前为止最长的单词,并使用它作为你的分配因子,这可能会比整个句子少得多。我们从1开始长度,以包含终止字符'\0'

代码语言:javascript
运行
复制
int longest = 1;
int tempLength = 1;
//Test if the the input string is empty
if (string[0] == '\0'){
    nWords=0;
}else{
    //First I need to check how long the input String is, 
    //as-well as count how many words are in the string.
    while (string[i] != '\0'){
        if (string[i] == ' '){
           if(tempLength > longest) {
               longest = tempLength;
           }
           nWords++;
        } else {
            tempLength++; // count characters of current word
        }
        i++;
    }
}

for (j=0;j<nWords;j++){
    temp[j] = (char*) malloc(longest*sizeof(char));
}

最后,您的代码的最后一部分需要修复。它不起作用,因为您正在使用j作为整个句子中的索引和单个单词中的索引。你从不重置j。让我们说第一个词是

代码语言:javascript
运行
复制
apple

一旦您遇到一个空间,您将拥有:

代码语言:javascript
运行
复制
j = 5
temp[0] = "apple"

现在,将k增量为1,但j保持不变,因此将开始从位置5而不是0存储下一个单词的字符:

代码语言:javascript
运行
复制
temp[1][5] = string[5];

而不是:

代码语言:javascript
运行
复制
temp[1][0] = string[5];

因此,您需要担心3个索引:

  • 遍历输入字符串的索引a
  • 对字符串中的单个单词进行迭代的索引b
  • 遍历单词数组的索引c

守则:

代码语言:javascript
运行
复制
int a, b, c;
for(a = 0, b = 0, c = 0; a < i; a++) {  // index i holds the total number of chars in input string
    if(string[a] != ' ') {
        temp[c][b] = string[a];
        b++;
    } else {
        temp[c][b] = '/0'; // add terminating character to current word
        b = 0;
        c++;
    }
}
info.argc = nWords;
info.argv = temp;
return info;
票数 2
EN

Stack Overflow用户

发布于 2014-09-11 21:43:38

很确定这就是你想要的。这应该只需要扫描一次字符串。索引数学有几个问题:

  • 您对i的计算效率很低。
  • 篮圈nWords看上去很可疑
  • 你似乎对终止每个单词不感兴趣,这是非常糟糕的。

尽管如此,请在调试器中仔细阅读下面的内容,看看它是如何工作的。

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

argsInfo getArgsInfo(const char * s)
{
    argsInfo info = {0,NULL};

    while (*s)
    {
        // find start of next word
        while (*s && isspace((unsigned char)*s))
            ++s;

        // find end of next word
        const char *beg = s;
        while (*s && !isspace((unsigned char)*s))
            ++s;

        if ((s - beg) > 0)
        {
            char **tmp = realloc(info.argv, (info.argc+1)*sizeof(*tmp));
            if (tmp)
            {
                info.argv = tmp;
                tmp[info.argc] = malloc((s - beg + 1) * sizeof(char));
                if (tmp[info.argc] != NULL)
                {
                    memcpy(tmp[info.argc], beg, s-beg);
                    tmp[info.argc++][s-beg] = 0; // <<= TERMINATE
                }
                else
                {
                    perror("Failed to allocate string");
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                perror("Failed to expand string pointer array");
                exit(EXIT_FAILURE);
            }
        }
    }
    return info;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25796630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档