Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 二维指针到二维指针_C_Arrays_Pointers_2d - Fatal编程技术网

C 二维指针到二维指针

C 二维指针到二维指针,c,arrays,pointers,2d,C,Arrays,Pointers,2d,我忘记了大部分的C,所以如果这是一个愚蠢的问题,请原谅我。因为我需要把一串单词分成单独的单词 #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 par

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

#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;
}
输入和输出示例:

输入:ax bcd efghij

输出:ax

如果删除k++行,输出将变为:ax bcd efghij


同样,如果我输入一个bc。当我在数组中运行时,只显示“a”

首先,这部分效率低下,但可以工作:

for (j=0;j<nWords;j++){
    temp[j] = (char*) malloc(i*sizeof(char));
}
最后,代码的最后一部分需要修复。它不起作用,因为在整个句子中使用j作为索引,在单个单词中使用j作为索引。你从不重置j。 假设第一个词是

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

j = 5
temp[0] = "apple"
现在将k增加到1,但j保持不变,因此将开始从位置5而不是0存储下一个单词的字符:

temp[1][5] = string[5];
而不是:

temp[1][0] = string[5];
因此,您需要担心3个索引:

在输入字符串上迭代的索引。 在字符串的单个单词上迭代的索引b。 循环遍历单词数组的索引c。 守则:

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;

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

你对i的计算效率很低。 新词语的使用似乎有问题 你似乎对终止每个单词都不感兴趣,这很糟糕。 也就是说,在调试器中非常仔细地浏览以下内容,以了解它是如何工作的

#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;
}

注意:当字符串[i]!='\0'{循环在出现连续空格时会计算单词数。我之前计划修复I这个东西,但直到你提到它之前,我没有想到使用最长的单词。谢谢你的第二部分也可以。我将查看它几次,直到我理解为什么你的有效,但我的无效。谢谢你的帮助!@user3365695非常欢迎你:查看我的编辑,了解您的最后一部分不起作用的原因。@user3365695我还建议您查看WhozCraig的解决方案,该解决方案更复杂/高级,但也更高效,因为它在一次输入扫描中完成所有操作。您选择argsInfo信息的静态声明而不是指针和动态分配的原因是什么?@DavidC.Rankin它不是静态的;它是自动的,并且OP的代码最初由value return使用,因此我正在寻找替换。老实说,无论如何,我不会动态分配argsInfo。不需要堆分配该结构;只需要指针数组及其内容。这是有意义的。我唯一的想法是以后创建的freeInfo函数只能释放char数组和指向char数组的指针,而不能同时释放指向struct的指针。这真是一个好奇。很好的解决方案。是的,如果我自己编写这个,我会通过地址传递argsInfo来填充并返回错误/成功作为函数结果,我讨厌那些不能告诉你它们是否工作的函数。类似地,一个freeArgsInfoargsInfo*ai也能很好地吻合这一点。这对你来说是一个很好的观察。很高兴你发现这个答案很有用。
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;
#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;
}