C - Strtok() ,将字符串拆分为 '\n' 但保留分隔符
C - Strtok() , split the string on '\n' but keep the delimiter
我的 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);
}
// .........
有什么方法可以让"empty sentence"(一个只是\n字符的句子)处理得当?
也许另一个函数可以代替 strtok()?
如果您正在从文件中读取输入,则可以使用流(使用 fopen()
)并使用 getline()
。
否则你可以编写一个函数来计算 \n
的数量,分配一个 char*
的数组,然后逐行填充它。
编辑:如果您不想自己编写代码,您可以通过一些小的研究轻松找到它
您在 strtok
的分隔符集中包含了换行符 \n
。
如果输入字符串是有效的读取,并且如果第一次调用 strtok
returns 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);
}
您可能应该按照评论的建议使用 strstr
或 strchr
,但是如果您的应用程序出于某种原因需要 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);
}
我的 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);
}
// .........
有什么方法可以让"empty sentence"(一个只是\n字符的句子)处理得当?
也许另一个函数可以代替 strtok()?
如果您正在从文件中读取输入,则可以使用流(使用 fopen()
)并使用 getline()
。
否则你可以编写一个函数来计算 \n
的数量,分配一个 char*
的数组,然后逐行填充它。
编辑:如果您不想自己编写代码,您可以通过一些小的研究轻松找到它
您在 strtok
的分隔符集中包含了换行符 \n
。
如果输入字符串是有效的读取,并且如果第一次调用 strtok
returns 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);
}
您可能应该按照评论的建议使用 strstr
或 strchr
,但是如果您的应用程序出于某种原因需要 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);
}