如何使strtok在令牌末尾包含换行符?

时间:2019-02-12 02:43:25

标签: c string ascii strtok

在我正在编写的程序中,我需要能够将输入文本文件标记为单词,进行一些编码,然后写入输出文件。问题是,我需要保留新行。

我尝试的方法是让strtok在一个单词的末尾保留换行符,但是,strtok在继续之前将只包含一个换行符。如果后面有换行符,它将成为其自己的令牌。如何更改此行为,以使令牌在移至下一个单词之前包含所有换行符?

int changeNewLine(char* p) {
    p = p + (strlen(p)-1);
    int newlines = 0;
        while(*p == '\n') {
            *p = '\0';
            newlines++;
            p--;
        }
    return newlines;
}

void main(int argc, char *argv[]) {
    FILE *inputfile = fopen(argv[1],"rw");
    FILE *outputfile = fopen("output.txt","wb");
    char buffer[128];
    char *token;
    char words[MAX_CODE][WORDLEN];
    int i = 0;
    unsigned short newlines[MAX_CODE];

    while(fgets(buffer, 128, inputfile)){
            token = strtok(buffer," ");
            while(token != NULL) {
                newlines[i] = changeNewLine(token);
                strcpy(words[i], token);
                i++;
                token = strtok(NULL," ");
            }
        }
    ...
}

上面是我的代码的一部分。想法是计算令牌中的换行符数量,然后稍后将其写回。

1 个答案:

答案 0 :(得分:1)

strtok已经在令牌中包含换行符,因为您使用的分隔符字符串不包含换行符。但是在您的程序中,由于fgets一次只能读取(最多)一行,所以在令牌中最多只能有一个。这就是它的全部目的。它永远不会给您一个包含两个或多个换行符的字符串,也不会包含最后一个字符以外的任何地方的换行符。

您的一般替代品是

  1. 先查看后续行,以发现其他换行符,或者
  2. 遇到以换行开头(因此不包含其他任何内容)的行时,会追溯更新前一行的换行计数。

替代方法(1)也可以包括采用完全不同的方法来读取输入,例如使用fread()读取的块或使用fgetc()一次读取字符。