有人可以解释为什么令牌总是会丢失单词而不是进入下一行吗?

Can some one explain why the token will always losing words instead of got to the next line?

int fp = open(file_name, O_CREAT | O_RDONLY, 0644);
if(fp < 0) {
    perror("erro ao abrir o ficheiro");
    _exit(-1);
}
char* notebook = myreadln(fp);
printf("%s\n====\n\n",notebook);
char* token = strtok(notebook, "\n");
while(token != NULL){
    printf("%s\n",token );
    new_line(d,token);
    token = strtok(NULL, "\n");
}
{...}

在这段代码中,我用一个文件加载了 char* notebook,因此,我想使用“\n”将该 char* 分成几行,但输出是这样的:

Isto vai dar sort
$ ls
Jk isto e que vai
$| sort
Isto faz mais 
$| head -1

====

Isto vai dar sort
        Isto vai dar sort
vai dar sort
        vai dar sort
dar sort
        dar sort
sort
        sort

有人可以解释为什么标记总是丢失单词而不是转到下一行吗?

我的函数new_line: 数据 d 是指向我的结构数据的指针

void new_line(Data d, char* s){
    char* aux = mystrdup(s);
    printf("\t%s\n",aux);

    int n = conta_palavras(aux); // number of words
    char** args = malloc((n+1)*sizeof(char*)); // create space for n words
    args[n] = NULL;

    char** words = escreve_palavras(aux, args);

    add(d,words);

}

mystrdup:

char * mystrdup (const char *s) {
    if(s == NULL) return NULL;          
    char *d = malloc (strlen (s) + 1); 
    if (d == NULL) return NULL;       
    strcpy (d,s);                    
    return d;                       
}

strtok 循环本身编写正确,没有函数 new_line() 它输出单行,因为它在 \n.[=23= 处断开字符串]

所以函数 new_line() 一定是在干扰它。让我猜猜怎么做。您希望将字符串分解为单词,这就是 new_line() 试图做的。当我用下一个代码实现它时 - 嘿!我得到了你得到的输出。

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

void new_line(char *d, char *str)
{
    char *tok = strtok(str, d);
}

int main() {
    char notebook[] = "Isto vai dar sort";
    char delim[] = " ";
    char* token = strtok(notebook, "\n");
    while(token != NULL){
        printf("%s\n", token );
        new_line(delim, token);
        token = strtok(NULL, "\n");
    }
}

程序输出:

Isto vai dar sort
vai dar sort
dar sort
sort

现在 strtok 不是 "reentrant",这意味着如果您在一个函数中使用它,则不能安全地在另一个函数中使用它。因此,让我们立即通过在空格处(以及任何尾随换行符)断开字符串来尝试获得您想要的答案:

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

int main() {
    char notebook[] = "Isto vai dar sort";
    char* token = strtok(notebook, " \n");    // added the space
    while(token != NULL){
        printf("%s\n", token );
        token = strtok(NULL, " \n");          // added the space
    }
}

现在程序输出为:

Isto
vai
dar
sort

我想这就是你想要的。

如果你想在不同的函数中使用 strtok,你应该使用 strtok_s (MSVC) 或 strtok_r (gcc)。