有没有办法用strtok
函数执行此操作?或任何建议?
示例:
Insert "hello world" to dbms
结果:
Insert
"hello world"
to
dbms
答案 0 :(得分:6)
strtok
或标准C库中的任何其他功能都无法为您执行此操作。要获得它,你必须自己编写代码,或者你必须在一些外部库中找到一些现有的代码。
答案 1 :(得分:4)
此函数采用分隔符,openblock和closeblock字符。块中将忽略分隔符,并且结束块字符必须与开始块字符匹配。空格和块上的示例拆分由引号和括号,大括号和<>定义。感谢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;
}
输出
这
包含
块
“a [引用区块”
和
一个
[括号内的“阻止”
和
答案 2 :(得分:2)
使用strtok()
没有运气。
有机会使用state machine。
#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>
答案 3 :(得分:0)
也许你可以使用正则表达式(即Regular expressions in C: examples?)
以下是您可以使用的正则表达式示例:/([\w]+)|(\"[\w\ ]+\")/gi
要使用正则表达式训练自己,您还应该使用:http://regex101.com/
答案 4 :(得分:0)
您可以执行第一次传递,其中strtok使用引号字符作为分隔符来分割字符串。然后执行第二次传递,将空格字符作为未引用的结果字符串的分隔符。
编辑添加工作源代码:
bool quotStr = (*stringToSplit == '\"');
char* currQuot = strtok(stringToSplit, "\"");
char* next = NULL;
while(currQuot)
{
if(quotStr)
{
printf("\"%s\"\n", currQuot);
quotStr = false;
}
else
{
// remember where the outer loop strtok left off
next = strtok(next, "\0");
// subdivide
char* currWord = strtok(currQuot, " ");
while(currWord)
{
printf("%s\n", currWord);
currWord = strtok(NULL, " ");
}
quotStr = true;
}
currQuot = strtok(next, "\"");
next = NULL;
}
我相信在空引用字符串的情况下,这仍然会失败,但是......
答案 5 :(得分:0)
我的解决方案是strtok()。它只对以Space-Quotes开头并以Quotes-Space
结尾的单词组合void split(char *argstring)
{
int _argc = 0;
char **_argv = malloc(sizeof(char*));
char *token;
int myFlag = 0;
for(token = strtok(argstring, " "); token != NULL; token = strtok(NULL, " "))
{
if (1 == myFlag)
{
//One of the previous token started with double quotes
if ('\"' == token[strlen(token)-1]) myFlag = 0; //This token ends with double quotes
_argv[_argc-1] = realloc(_argv[_argc-1], strlen(_argv[_argc-1]) + strlen(token) + 2); //Enlarge the previous token
strcat(_argv[_argc-1], " ");
strcat(_argv[_argc-1], token);
}
else
{
if ('\"' == token[0]) myFlag = 1; //This token starts with double quotes
_argv = realloc(_argv, (_argc + 1) * sizeof(char*)); //Add one element to the array of strings
_argv[_argc] = m2m_os_mem_alloc(strlen(token) + 1); //Allocate the memory for the Nth element
strcpy(_argv[_argc], token); //Copy the token in the array
_argc++;
}
}
do
{
m2m_os_mem_free(_argv[_argc--]);
} while (_argc >= 0);
}