C 二维指针到二维指针
我忘记了大部分的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
#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;
}