C - Strtok(),将字符串拆分为'\ n',但保留分隔符

时间:2016-10-31 17:41:52

标签: c delimiter strtok

我的C程序存在以下问题。它的一部分功能是读取一些文本并将其拆分成句子,然后将这些句子写入文件中。

我使用Strtok()在句子中分割文本块(当\ n出现时句子结束)但是当有一个句子只包含一大块文本中的\ n字符时,如:

//////////////////////////////

您好,这是一些示例文本
   这是第二句

上面的句子只是一个新行    这是最后一句话。

/////////////////////////////

文件的输出如下:

0您好,这是一些示例文本
   1这是第二句    2上面的句子只是一个新的线    3这是最后一句话。

/////////////////////////////////////////////// /////

虽然它应该是:

0您好,这是一些示例文本
 1这是第二句  2
 3上面的句子只是\ n
 4这是最后一句话。

////////////////////////////////////

保存字符串的文件应该作为一个日志文件,这就是为什么我必须将文本块拆分为\ n,然后在将每个句子写入文件之前将一个整数放在前面。

这是与此功能相关的代码:

int counter = 0; // Used for counting
const char s[2] = "\n"; // Used for tokenization

// ............

char *token;
      token = strtok(input,s);
      while(token != NULL){
        fprintf(logs, "%d ", counter);
        fprintf(logs, "%s\n" , token); // Add the new line character here since it is removed from the tokenization process
        counter++;
        token = strtok(NULL, s);
      }

// .........

有没有办法让一个特殊的情况下,当一个“空句子”(一个只是一个字符的句子)来正确处理它?<​​/ p>

也许另一个函数可以代替strtok()吗?

3 个答案:

答案 0 :(得分:2)

您可能应该使用strstrstrchr作为评论建议,但如果您的申请由于某种原因需要strtok,您可以保存每个句子结尾的位置,确定使用指针算法顺序发生多个换行符(\n)。

粗略未经测试的示例代码:

int counter = 0; // Used for counting
const char* last_sentence;


// ............
      last_sentence = input;
      char *token;
      token = strtok(input,"\n");
      while(token != NULL){
        int i;
        for (i = (token - last_sentence);i > 1; i--){
          // this gets called once for each empty line.
          fprintf(logs, "%d \n", counter++);
        }
        fprintf(logs, "%d %s\n", counter++, token);

        last_sentence = token + strlen(token);
        token = strtok(NULL, "\n");
      }

// .........

编辑:添加了strchr

的示例

使用strchr同样简单,如果不是更容易,尤其是因为您只有一个分隔符。下面的代码将你的句子分开,并将它们分开。它只是打印它们,但您可以轻松扩展它以达到您的目的。

#include <stdio.h>
#include <string.h>
const char* sentences = "Hello, this is some sample text\n"
                        "This is the second sentence\n"
                        "\n"
                        "The sentence above is just a new line\n"
                        "This is the last sentence.\n";

void parse(const char* input){
  char *start, *end;
  unsigned count = 0;

  // the cast to (char*) is because i'm going to change the pointer, not because i'm going to change the value.
  start = end = (char*) input; 

  while( (end = strchr(start, '\n')) ){
      printf("%d %.*s", count++, (int)(end - start + 1), start);
      start = end + 1;
  }
}

int main(void){
  parse(sentences);
}

答案 1 :(得分:0)

如果您正在从文件中读取输入,则可以使用流(使用fopen())并使用getline()

否则,您可以编写一个计算\n数量的函数,分配一个char*数组,并逐行填充。

编辑:如果您不想自己编写代码,可以通过一些小型研究轻松找到它

答案 2 :(得分:0)

您在\n的分隔符集中添加了换行符strtok

如果输入字符串是有效读取,并且第一次调用strtok返回NULL,那么它就是一个空白行,然后您可以处理。

token = strtok(input,s);
if(token == NULL) {
    fprintf(logs, "%d\n", counter);
    counter++;
}
while(token != NULL){                   // the `while` serves as `else`
    fprintf(logs, "%d ", counter);
    fprintf(logs, "%s\n" , token);
    counter++;
    token = strtok(NULL, s);
}