如何在c中的字符数组中用strtok划分单词

时间:2017-02-13 01:46:13

标签: c arrays pointers strtok

我有一个名为excuses的结构有字符,我需要存储至少20个借口。然后,我需要将每个借口的每个单词分成一个数组。

¿我怎么能这样做?

#define excuseLength 256

typedef struct{
    char sentence[excuseLength];
}excuse;

excuse listExcuses[20];

for (int listExcuses_i = 0; listExcuses_i < 20; listExcuses_i++)
{
    char *input;
    scanf("%s", input);
    strcpy(listExcuses[listExcuses_i].sentence, input);

    char* token = strtok(input, " ");
    while(token != NULL){
        printf("token: %s\n", token);
        token = strtok(NULL, " ");
    }
}

2 个答案:

答案 0 :(得分:2)

以下是您可以添加到解决方案中的一些内容:

  • 检查fgets()是否有返回值,因为它在出错时返回NULL
  • 如果您仍然决定使用scanf(),请务必使用scanf("%255s", input)代替char input[256]。使用格式说明符%255s而不是simpe %s检查过多的输入。总的来说,最好使用fgets()读取输入。
  • 删除'\n'附加的fgets()个字符。这也有助于检查您输入的字符数是否超过256input的限制,并且您的句子在每个字符后都没有后续换行符。如果您不删除此换行符,则您的strtok()分隔符必须为" \n"
  • 代码中的
  • #define常量,并使用const char*表示字符串文字,例如strtok()的分隔符。
  • 您还可以添加一些代码来检查来自fgets()的空输入。您可以简单地使用一个单独的计数器,并且仅为找到的有效字符串递增此计数器。
  • struct有一个成员也很奇怪,通常结构包含多个成员。您可以简单地绕过使用结构并使用声明为char listexcuses[NUMEXCUSES][EXCUSELENGTH]的2D char数组。此数组最多可容纳20个字符串,每个字符串的最大长度为256

以下是您的方法的一些修改代码:

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

#define EXCUSELENGTH 256
#define NUMEXCUSES 20

typedef struct {
    char sentence[EXCUSELENGTH];
} excuse;

int main(void) {
    excuse listexcuses[NUMEXCUSES];
    char input[EXCUSELENGTH] = {'\0'};
    char *word = NULL;
    const char *delim = " ";
    size_t slen, count = 0;

    for (size_t i = 0; i < NUMEXCUSES; i++) {

        printf("\nEnter excuse number %zu:\n", count+1);
        if (fgets(input, EXCUSELENGTH, stdin) == NULL) {
            fprintf(stderr, "Error from fgets(), cannot read line\n");
            exit(EXIT_FAILURE);
        }

        slen = strlen(input);
        if (slen > 0 && input[slen-1] == '\n') {
            input[slen-1] = '\0';
        } else {
            fprintf(stderr, "Too many characters entered in excuse %zu\n", count+1);
            exit(EXIT_FAILURE);
        }

        if (*input) {
            strcpy(listexcuses[count].sentence, input);
            count++;

            printf("\nTokens found:\n");
            word = strtok(input, delim);
            while (word != NULL) {
                printf("%s\n", word);
                word = strtok(NULL, delim);
            }  
        }
    }

    return 0;
} 

由于您最终需要在某处存储这些令牌,因此您需要另一种存储此数据的形式。由于您不知道可以获得多少令牌,或者每个令牌有多长,因此您可能需要使用char **tokens之类的内容。这不是数组,但它是指向指针的指针。使用它将允许存储任何数量的单词和每个单词的任何长度。您需要动态内存分配。这篇文章中的答案将有所帮助。

答案 1 :(得分:1)

我更改了fgets的scanf并初始化了char输入[256],现在它可以工作了!

#define excuseLength 256
#define numberExcuses 20

typedef struct{
    char sentence[excuseLength];
}excuse;

excuse listExcuses[20];

for (int listExcuses_i = 0; listExcuses_i < numberExcuses; listExcuses_i++)
{
    char input[256];
    scanf("%s", input);
    fgets(input, 256, stdin);
    strcpy(listExcuses[listExcuses_i].sentence, input);

    char* token = strtok(input, " ");
    while(token != NULL){
        printf("token: %s\n", token);
        token = strtok(NULL, " ");
    }
}