C将字符串拆分为单个单词并将单个单词保存在数组中

时间:2016-02-01 23:56:36

标签: c pointers

所以让我们说用户输入"编程一两三"。我将其保存在userTyped数组中并将其传递给parse()函数。我需要使用parse()函数来实现

userargv [0]是程序

userargv [1]是一个

userargv [2]是两个

我可以说它必须是涉及指针的东西,但我能解决它。代码如下:

int main(int argc, char **argv)
{
char userTyped[1000];

char* userargv[100];//this is where i need the parse() function to store the arguments to pass to execv

printf("typesomething>");

fgets(userTyped, 1000, stdin);

parse(userTyped, &userargv);

return 0;
}



int parse(char* userTyped, char* userargv){

const char whitespace[2] = " "; //the deliminator
char *strings;

strings = strtok(userTyped, whitespace);

while( strings != NULL )
{
    strings = strtok(NULL, whitespace);

 }
//THIS ALL WORKS, BUT I NEED TO DO SOMETHING LIKE userargv[i] = strings;
//OR *userargv[i] = &strings;
//OR SOMETHING LIKE THAT.

return 0;
}

2 个答案:

答案 0 :(得分:0)

你必须分配一个字符串数组(char **),然后分配它的每个元素,然后将所有找到的字符串复制回来;

// nb: the function prototype has been slightly modified 
char** parse(char* userTyped, int *nargs){

    const char whitespace[2] = " "; //the deliminator
    char *strings;
    char **arr;
    int n = 0; // initially no element allocated

    strings = strtok(userTyped, whitespace);

    while( strings != NULL )
    {
        if( n ){ // if there are already allocated elements?
            arr = realloc( arr, ( n + 1 ) * sizeof( char** ) );
        }else{
            arr = malloc( ( n + 1 ) * sizeof( char* ) );
        }

        if( !arr ){
            perror( "parse" );
            exit( -1 );
        }

        // duplicate strings
        arr[ n ] = malloc( strlen( strings )+1 ); 

        if( !arr[ n ] ){
            perror( "parse" );
            exit( -2 );
        }
        strcpy(arr[ n ] , strings); // make a copy of the string

        n++;

        strings = strtok(NULL, whitespace);

    }


    // call freeStrArr when done with arr;
    //
    *nargs  = n; // save array size;
    return arr; // return string array
}

// this how to free the returned array;
void freeStrArr(char ** strarr,int n){
    while( n ){
        n--;
        free( strarr[ n ] );
    }
    free( strarr);
}

答案 1 :(得分:0)

当你想到从解析函数中获得什么时,你知道你会希望指针数组指向包含usertyped中单个单词的已分配内存块,但你还需要知道有多少单独的单词。由于您将指针数组作为参数传递给函数本身进行操作,因此您只需返回给定字符串中单个单词的数量。您可以使用以下形式的内容:

int parse (char **words, char *str);

注意:通过传递指针数组100),您只能使用100个单词,而无法重新分配如果你超过这个数字。你可以传递一个指针到指针指向char * 并在需要时重新分配。另请注意,如果你没有将负数作为错误条件返回,选择size_t作为回报可能更合适。)

使用strtok时,您可以通过定制分隔符 strtok使用来定制strtok单独字词的位置和方式。 (例如,在句子"This. Not that."中,如果只是打破spaces,您的分隔词也会包含'.'字符。为防止这种情况,您可以在分隔符 '.'使用的字符串中包含strtok字符。从这个角度来看,将分隔符列表作为参数传递给parse函数也是有意义的:

int parse (char **words, char *str, char *delims);

您可以使用指定为参数的原始字符串对strtok进行初始调用,然后在传递NULL作为参数的单独循环中完成剩余字符串的解析。或者您可以在单个for循环中处理这两种情况。这只是一个形式问题,或者很好。一个例子:

int parse (char **words, char *str, char *delims)
{
    int n = 0;
    char *p;

    for (p = strtok (str, delims); p; p = strtok (NULL, delims)) 
    {
        words[n++] = strdup (p);    /* allocate/copy */

        if (n == MAXW) { /* limit reached - realloc/break */
            fprintf (stderr, "warning: MAXW reached.\n");
            break;
        }
    }

    return n;
}

一个简单的示例程序,指定分隔符并将它们与数组和字符串一起传递给parse函数可以是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum { MAXW = 100, MAXC = 1000 };

int parse (char **words, char *str, char *delims);

int main (void) {

    char usertyped[MAXC] = {0};
    char *userargv[MAXW] = {NULL};
    char *delims = " \t\n.,:;";
    int i, nwords = 0;

    printf ("typesomething> ");

    if (!fgets (usertyped, 1000, stdin)) {
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    if (!(nwords = parse (userargv, usertyped, delims))) {
        fprintf (stderr, "error: parsed no words.\n");
        return 1;
    }

    for (i = 0; i < nwords; i++)
        printf ("userargv[%2d] : %s\n", i, userargv[i]);

    for (i = 0; i < nwords; i++)
        free (userargv[i]);

    return 0;
}

int parse (char **words, char *str, char *delims)
{
    int n = 0;
    char *p;

    for (p = strtok (str, delims); p; p = strtok (NULL, delims)) 
    {
        words[n++] = strdup (p);    /* allocate/copy */

        if (n == MAXW) { /* limit reached - realloc/break */
            fprintf (stderr, "warning: MAXW reached.\n");
            break;
        }
    }

    return n;
}

示例使用/输出

$ ./bin/strtok_parse
typesomething> a quick brown fox jumps over the laszy dog.
userargv[ 0] : a
userargv[ 1] : quick
userargv[ 2] : brown
userargv[ 3] : fox
userargv[ 4] : jumps
userargv[ 5] : over
userargv[ 6] : the
userargv[ 7] : laszy
userargv[ 8] : dog

一些额外的笔记。通常在C中,样式避免使用 camelCase 变量。因此usertyped代替userTyped以上。 (另一种形式问题)。由于strdup正在为您分配内存,因此您应该检查以确保返回不是NULL(与malloccalloc一样)以防止内存耗尽。另请注意,您可以#define SOMECONST value或如上所述使用enum来定义常量。如果您还有其他问题,请与我们联系。