【问题标题】:In C how do I break a multiple word string stored in a variable into an array with each word holding an array value在 C 中,如何将存储在变量中的多个单词字符串分解为一个数组,每个单词都保存一个数组值
【发布时间】:2015-10-03 01:53:39
【问题描述】:

我要做的是让用户输入多个单词,这些单词当前位于一个变量中,每个单词都存储在一个数组值中。

例如,用户输入以下内容:“在课程中” 它存储在单个变量“输入”中

如何将该变量的每个单词放入这样的数组中:

array[0] = When
array[1] = in
array[2] = the
array[3] = course
etc.

我的最终目标是能够针对输入的第一个单词运行 if 语句,并使用它来确定接下来的操作过程。

例如用户输入:在课程中添加

然后我针对它运行一个 if 语句:

if array[0] = ADD
then  file_ptr = fopen ("file1.txt", "a+");

            fprintf(file_ptr, "%s" , buf," ");
                    }
            fclose(file_ptr);
else if array[0] = delete

然后删除等

谢谢大家的帮助。

【问题讨论】:

    标签: c arrays string parsing


    【解决方案1】:

    我不太明白你的问题,但我会先从这个函数开始,所以你可以拆分你的字符串:

    C 库函数 char *strtok(c​​har *str, const char *delim) 使用分隔符 delim 将字符串 str 分成一系列标记。

    char *strtok(char *str, const char *delim)
    

    参数 str -- 这个字符串的内容被修改和破坏 成更小的字符串(令牌)。

    delim -- 这是包含分隔符的 C 字符串。这些可能 因呼叫而异。

    source

    【讨论】:

    • @ff210327 试着改进你的问题,也许我可以做更多的帮助。
    • 实际上我认为这很有帮助。为了澄清,我试图获取一个包含多个单词的变量,并将每个单词分解为它自己的数组位置数组 [0]、数组 [1] 等。这样稍后我可以在程序中运行一个 if 语句第一个数组值并根据用户输入的单词执行不同的函数。
    【解决方案2】:

    我会在开头使用strtok。我知道这是很多代码,但我编写它向您展示了如何正确管理动态分配的内存以及如何正确使用 strtokrealloc 之类的函数,因为您会看到这些函数的很多错误用法。

    当然你可以通过更高的性能让它变得更好,但就像我说的,我想向你展示更多如何使用动态分配的内存。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char *copy_str(const char *str)
    {
        if(str == NULL)
            return NULL;
    
        char *ptr = malloc(strlen(str) + 1);
        if(ptr)
        {
            strcpy(ptr, str);
            return ptr;
        }
        return NULL;
    }
    
    char **add_new_word(char **words, char *newword)
    {
        int len;
        for(len=0; words && words[len]; ++len);
    
        char **tmp = realloc(words, (sizeof *words)*(len + 2));
        if(tmp == NULL)
            return NULL;
        tmp[len] = newword;
        tmp[len+1] = NULL;
        return tmp;
    }
    
    
    char **get_words(const char *sentence)
    {
        char **strings = NULL, **tmp_strings;
        char *tmp_sentence = copy_str(sentence);
        char *tmp_sentence_orig = tmp_sentence;
        if(tmp_sentence == NULL)
            return NULL;
    
        char *tmp_word = copy_str(strtok(tmp_sentence, " "));
        if(tmp_word == NULL)
        {
            free(tmp_sentence_orig);
            return NULL;
        }
    
        tmp_strings = add_new_word(strings, tmp_word);
        if(tmp_strings == NULL)
        {
            free(tmp_sentence_orig);
            return NULL;
        }
        strings = tmp_strings;
    
        while(tmp_word = copy_str(strtok(NULL, " ")))
        {
            tmp_strings = add_new_word(strings, tmp_word);
            if(tmp_strings == NULL)
            {
                free(tmp_word);
                free(tmp_sentence_orig);
                return strings; // got all words we could
            }
            strings = tmp_strings;
        }
    
        free(tmp_sentence_orig);
        return strings;
    }
    
    void free_words(char **words)
    {
        if(words == NULL)
            return;
    
        int i;
        for(i=0; words[i]; ++i)
            free(words[i]);
    
        free(words);
    }
    
    int main(void)
    {
        char **words = get_words("When in the course");
    
        if(words == NULL)
            return 1;
    
        int i;
        for(i = 0; words[i]; ++i)
            printf("word #%d: '%s'\n", i+1, words[i]);
    
        free_words(words);
        return 0;
    }
    

    正如你在valgrind看到的那样:

    ==31202== Memcheck, a memory error detector
    ==31202== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
    ==31202== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
    ==31202== Command: ./a
    ==31202==
    word #1: 'When'
    word #2: 'in'
    word #3: 'the'
    word #4: 'course'
    ==31202==
    ==31202== HEAP SUMMARY:
    ==31202==     in use at exit: 0 bytes in 0 blocks
    ==31202==   total heap usage: 9 allocs, 9 frees, 150 bytes allocated
    ==31202==
    ==31202== All heap blocks were freed -- no leaks are possible
    ==31202==
    ==31202== For counts of detected and suppressed errors, rerun with: -v
    ==31202== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    

    【讨论】:

    • 我看到了对数组的静态赋值是如何工作的,如果用户输入是可变的,它将如何工作?你把 char **words = get_words("When in the course");如果我只有一个已经在它自己的变量中的用户输入怎么办?
    • 静态赋值是什么意思?无论您使用字符串文字(如在我的示例中)还是带有字符串的变量都不会改变get_words 的工作方式,对于编译器来说,这两者之间没有区别(实际上有但更多的是他们在内存中的位置分配)。您可以这样声明 main:int main(int argc, char** argv),然后将其命名为 get_words(argv[1]),这样就可以了。也可以制作char line[1024]; fgets(line, sizeof line, stdin);char **words = get_words(line)。试试看吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 2018-05-09
    相关资源
    最近更新 更多