如何在c中的字符数组中用strtok划分单词
how to divide words with strtok in an array of chars in c
我有一个名为 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, " ");
}
}
我更改了 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, " ");
}
}
以下是您可以添加到解决方案中的一些内容:
- 检查
fgets()
的 return 值,因为它 returns NULL
出错。
- 如果您决定仍然使用
scanf()
,请务必使用 scanf("%255s", input)
代替 char input[256]
。使用格式说明符 %255s
而不是简单的 %s
检查输入过多。总的来说,使用 fgets()
读取输入更好。
- 删除
fgets()
附加的 '\n'
个字符。这也有助于检查您在 input
中输入的字符数没有超过 256
的限制,并且您的句子在每个句子后没有尾随换行符。如果您不删除此换行符,那么您的 strtok()
定界符将必须改为 " \n"
。
#define
常量,并使用 const char*
作为字符串文字,例如 strtok()
的分隔符。
- 您还可以添加一些代码来检查来自
fgets()
的空输入。您可以简单地使用一个单独的计数器,并且只为找到的有效字符串增加该计数器。
struct
只有一个成员也很奇怪,通常结构包含多个成员。您可以简单地绕过使用结构并使用声明为 char listexcuses[NUMEXCUSES][EXCUSELENGTH]
的二维字符数组。该数组最多可以容纳 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] = {'[=10=]'};
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] = '[=10=]';
} 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
之类的东西。这不是数组,而是指向指针的指针。使用这个将允许存储任意数量的单词和每个单词的任意长度。为此,您将需要动态内存分配。 post 中的答案会有所帮助。
我有一个名为 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, " ");
}
}
我更改了 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, " ");
}
}
以下是您可以添加到解决方案中的一些内容:
- 检查
fgets()
的 return 值,因为它 returnsNULL
出错。 - 如果您决定仍然使用
scanf()
,请务必使用scanf("%255s", input)
代替char input[256]
。使用格式说明符%255s
而不是简单的%s
检查输入过多。总的来说,使用fgets()
读取输入更好。 - 删除
fgets()
附加的'\n'
个字符。这也有助于检查您在input
中输入的字符数没有超过256
的限制,并且您的句子在每个句子后没有尾随换行符。如果您不删除此换行符,那么您的strtok()
定界符将必须改为" \n"
。 #define
常量,并使用const char*
作为字符串文字,例如strtok()
的分隔符。- 您还可以添加一些代码来检查来自
fgets()
的空输入。您可以简单地使用一个单独的计数器,并且只为找到的有效字符串增加该计数器。 struct
只有一个成员也很奇怪,通常结构包含多个成员。您可以简单地绕过使用结构并使用声明为char listexcuses[NUMEXCUSES][EXCUSELENGTH]
的二维字符数组。该数组最多可以容纳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] = {'[=10=]'};
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] = '[=10=]';
} 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
之类的东西。这不是数组,而是指向指针的指针。使用这个将允许存储任意数量的单词和每个单词的任意长度。为此,您将需要动态内存分配。 post 中的答案会有所帮助。