我正在逐行解析C文件。这里是什么,我试图做一个为例:C - 查找单词并获取下一个
我有例如线: word word word WORDTOFIND: word1 word2 word word
我想要做的是:当我发现这个词WORDTOFIND
,得到两个接下来的话(word1
在这种情况下为word2
)。在C中有一种简单的方法吗?我知道strstr功能,但我找不到一个方法来得到接下来的两个词word1
和word2
后,我找到了一个好的。
我正在逐行解析C文件。这里是什么,我试图做一个为例:C - 查找单词并获取下一个
我有例如线: word word word WORDTOFIND: word1 word2 word word
我想要做的是:当我发现这个词WORDTOFIND
,得到两个接下来的话(word1
在这种情况下为word2
)。在C中有一种简单的方法吗?我知道strstr功能,但我找不到一个方法来得到接下来的两个词word1
和word2
后,我找到了一个好的。
一种方法是这样的:
int main(void)
{
char *str = "rated rat cat bat hat";
char *key = "rat ";
char *pointer = NULL;
char nwords = 2;
if ((pointer = strstr(str, key)) != NULL)
{
while (*pointer != ' ') pointer++;
while (nwords >= 0)
{
printf("%c", *pointer);
if (*pointer == ' ') {
nwords--;
} else if (*pointer == '\0') {
exit(0);
}
pointer++;
}
}
}
这种方法非常简单。如果在“老鼠”之前有“评分”,该怎么办?如果单词被多个空格或多个单词分隔,该怎么办?如问题中的标点符号一样?最糟糕的是,如果少于两个单词的话,这段代码会尝试读取原始字符串。 –
你可以尝试这样的形式给出,使用strtok
解析在每一个空间的话。此代码还使用malloc
和realloc
为字符串数组分配空间,并在需要时增大该空间。
的代码看起来是这样的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXCHAR 100
void exit_if_null(void *ptr, const char *msg);
char *stripped_word(char *word);
int
main(int argc, char const *argv[]) {
FILE *filename;
char line[MAXCHAR];
char *word, *newword;
char **allwords;
int init_size = 8, count = 0, i;
const char *key = "WORDTOFIND";
filename = fopen("files.txt", "r");
if (filename == NULL) {
fprintf(stderr, "%s\n", "Error reading file!");
exit(EXIT_FAILURE);
}
allwords = malloc(init_size * sizeof(*allwords));
exit_if_null(allwords, "Initial Allocation");
while (fgets(line, MAXCHAR, filename) != NULL) {
word = strtok(line, " \n");
while (word != NULL) {
if (count == init_size) {
init_size *= 2;
allwords = realloc(allwords, init_size * sizeof(*allwords));
}
allwords[count] = malloc(strlen(word)+1);
exit_if_null(allwords[count], "Initial Allocation");
newword = stripped_word(word);
strcpy(allwords[count], newword);
count++;
word = strtok(NULL, " \n");
free(newword);
}
}
for (i = 0; i < count; i++) {
if (strcmp(key, allwords[i]) == 0) {
printf("Next two words:\n");
printf("%s\n", allwords[i+1]);
printf("%s\n", allwords[i+2]);
}
free(allwords[i]);
allwords[i] = NULL;
}
free(allwords);
allwords = NULL;
return 0;
}
void
exit_if_null(void *ptr, const char *msg) {
if (!ptr) {
printf("Unexpected null pointer: %s\n", msg);
exit(EXIT_FAILURE);
}
}
char
*stripped_word(char *word) {
int i, pos = 0;
char *result;
result = malloc(strlen(word)+1);
exit_if_null(result, "Initial Allocation");
for (i = 0; word[i] != '\0'; i++) {
if (isalpha(word[i]) || isdigit(word[i])) {
result[pos++] = word[i];
}
}
result[pos] = '\0';
return result;
}
一种方法是将行解析成词的数组因此很容易知道,如果接下来的两个词是什么/。然而,这种替代方法稍微昂贵一点。 – Droppy
所以你想在这种情况下得到'word1'和'word2'?请在问题中更具体一些,或者展示一些例子。 – RoadRunner
我编辑了这篇文章,很抱歉,如果我不清楚。是的,在这种情况下,我想要word1和word2。 – Whin3