有没有办法用strtok功能做到这一点?或任何建议?
示例:
Insert "hello world" to dbms
Run Code Online (Sandbox Code Playgroud)
结果:
Insert
"hello world"
to
dbms
Run Code Online (Sandbox Code Playgroud)
此函数采用定界、开放块和封闭块字符。块内的定界字符被忽略,结束块字符必须与开始块字符匹配。示例分隔空间和块由引号和方括号、大括号和 <> 定义。感谢 Jongware 的评论!
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char *strmbtok ( char *input, char *delimit, char *openblock, char *closeblock) {
static char *token = NULL;
char *lead = NULL;
char *block = NULL;
int iBlock = 0;
int iBlockIndex = 0;
if ( input != NULL) {
token = input;
lead = input;
}
else {
lead = token;
if ( *token == '\0') {
lead = NULL;
}
}
while ( *token != '\0') {
if ( iBlock) {
if ( closeblock[iBlockIndex] == *token) {
iBlock = 0;
}
token++;
continue;
}
if ( ( block = strchr ( openblock, *token)) != NULL) {
iBlock = 1;
iBlockIndex = block - openblock;
token++;
continue;
}
if ( strchr ( delimit, *token) != NULL) {
*token = '\0';
token++;
break;
}
token++;
}
return lead;
}
int main (int argc , char *argv[]) {
char *tok;
char acOpen[] = {"\"[<{"};
char acClose[] = {"\"]>}"};
char acStr[] = {"this contains blocks \"a [quoted block\" and a [bracketed \"block] and <other ]\" blocks>"};
tok = strmbtok ( acStr, " ", acOpen, acClose);
printf ( "%s\n", tok);
while ( ( tok = strmbtok ( NULL, " ", acOpen, acClose)) != NULL) {
printf ( "%s\n", tok);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出
这
包含
块
“一个[引用块”
和
一个
[括起来的“块]
和
没有运气使用strtok()。
使用状态机的有趣机会。
#include <stdio.h>
void printstring(const char *frm, const char *to) {
fputc('<', stdout); // <...>\n Added for output clarity
while (frm < to) {
fputc(*frm++, stdout);
}
fputc('>', stdout);
fputc('\n', stdout);
}
void split_space_not_quote(const char *s) {
const char *start;
int state = ' ';
while (*s) {
switch (state) {
case '\n': // Could add various white-space here like \f \t \r \v
case ' ': // Consuming spaces
if (*s == '\"') {
start = s;
state = '\"'; // begin quote
} else if (*s != ' ') {
start = s;
state = 'T';
}
break;
case 'T': // non-quoted text
if (*s == ' ') {
printstring(start, s);
state = ' ';
} else if (*s == '\"') {
state = '\"'; // begin quote
}
break;
case '\"': // Inside a quote
if (*s == '\"') {
state = 'T'; // end quote
}
break;
}
s++;
} // end while
if (state != ' ') {
printstring(start, s);
}
}
int main(void) {
split_space_not_quote("Insert \"hello world\" to dbms");
return 0;
}
<Insert>
<"hello world">
<to>
<dbms>
Run Code Online (Sandbox Code Playgroud)