我忘了大部分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;
}
最后一排。我觉得问题就在那里。info.argv = temp;
这就是这个结构的样子:
typedef struct {
int argc;
char ** argv;
} argsInfo;
输入和输出示例:
输入:"ax bcd efghij“
输出: ax
如果删除k++行,输出为:
同样,如果我输入一个bc.c,在运行数组时,只有'a‘才会出现。
发布于 2014-09-11 21:14:40
首先,这部分效率很低,但效果很好:
for (j=0;j<nWords;j++){
temp[j] = (char*) malloc(i*sizeof(char));
}
您使用的是i
的值,它将等于原始输入字符串中的字符总数。这意味着,对于每个单独的单词,您都有足够的空间存储原来的句子,这是浪费空间。例如,当你在计算单词时,你也可以记住到目前为止最长的单词,并使用它作为你的分配因子,这可能会比整个句子少得多。我们从1开始长度,以包含终止字符'\0'
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
。让我们说第一个词是
apple
一旦您遇到一个空间,您将拥有:
j = 5
temp[0] = "apple"
现在,将k
增量为1,但j
保持不变,因此将开始从位置5而不是0存储下一个单词的字符:
temp[1][5] = string[5];
而不是:
temp[1][0] = string[5];
因此,您需要担心3个索引:
a
。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;
发布于 2014-09-11 21:43:38
很确定这就是你想要的。这应该只需要扫描一次字符串。索引数学有几个问题:
i
的计算效率很低。nWords
看上去很可疑尽管如此,请在调试器中仔细阅读下面的内容,看看它是如何工作的。
#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;
}
https://stackoverflow.com/questions/25796630
复制相似问题