替换字符串

我正在做像excel这样的事情,我有这样的事情:

1 2 3 A1 B1 C1 

它替换指定内容的内容,其中A1替换1的内容.B1替换2 …等的内容…

我正在使用多维数组,我做这样的事情:

 int offset = 0, readCharCount; while(sscanf(matris[i][c] + offset, "%c%d%*c%n", &col, &linha, &readCharCount) == 2){ //printf("%c, %d\n", col, linha); //strcpy(matris[i][c], matris[linha-1][col - 'A']); offset += readCharCount; //printf(" {%c, %d}", col, linha); //printf("\n"); } 

但是当我有A1 + B1 + C1和其他东西时,我不能替换总内容,因为其他参考将被删除….

所以,在单元格,A1 + B1 + C1,我想改变B1指定的内容….我想这样:

 This -> A1+B1+C1 to -> 1+2+3 

….

谢谢。

您可能只是重用此c ++解决方案 (通过硬编码char*替换通用迭代器)。

我给了它一个旋转。 但是,我想发出一个警告:看起来你正在尝试实现一个表达式解析器。 我强烈建议你

  • 手动(递归下降)解析器
  • 使用flex / bison(或lex / yacc)

所以你不要把自己描绘成C中容易出错的文本处理的尴尬角落。

编辑:我用C ++重写了你的C程序 ; 你可以看到它在这里工作 。

编辑2: C程序在纯C中的另一个修复: http//ideone.com/ExnufJ 现在也更新为支持迭代扩展

答案只关注纯C方法:

那么,让我们开始吧。 我假设了一个样本“电子表格”(它可能包含数字而不是字符串):

 const char* cells[][4] = { /* ABCD */ { "the" , "lazy" , "cow" , "jumped" }, /* 1 */ { "over" , "the" , "quick", "brown" }, /* 2 */ { "paper", "packages", "tied" , "up" }, /* 3 */ { "with" , "silver" , "white", "winters" }, /* 4 */ { "that" , "melt" , "fox" , "springs" }, /* 5 */ }; 

仅使用两个助手:

 const char* get_cell_value(const char* coordinate_b, const char* coordinate_e); char* expand_cell_references(const char* f, const char* const l, char* o); /*the magic engine*/ 

我们可以编写以下演示程序:

 int main() { const char in[] = "The C2 D2 C5 D1 A2 B2 B1 dog!"; char out[1024] = {0}; expand_cell_references(in, in+strlen(in), out); puts(out); /* "The quick brown fox jumped over the lazy dog!" */ return 0; } 

根据评论打印着名的测试短语。 现在, get_cell_value非常简单:

 const char* get_cell_value(const char* coordinate_b, const char* coordinate_e) { size_t col = 0, row = 0; const char* it; for (it=coordinate_b; it != coordinate_e; ++it) { if (*it >= 'A' && *it <= 'Z') col = 26*col + (*it - 'A'); if (*it >= '0' && *it <= '9') row = 10*row + (*it - '0'); /* or use atoi and friends */ } row--; /* 1-based row nums in Excel */ return cells[row][col]; /* 1-based indexes in Excel */ } 

并且expand_cell_references稍微复杂一些,是一个简单的DFA解析器:

 char* expand_cell_references(const char* f, const char* const l, char* o) { enum parser_state { other, in_coord_col, in_coord_row } state = other; /*temporary storage for coordinates being parsed:*/ char accum[16] = {0}; char* accit = accum; while (f!=l) { switch(state) /*dummy, the transitions flow in fallthrough order for now*/ { case other: *(accit = accum) = 0; /*reset the accumulator*/ while (f!=l && !(*f>='A' && *f<='Z')) *o++ = *f++; /*fallthrough*/ case in_coord_col: while (f!=l && *f>='A' && *f<='Z') *accit++ = *f++; /*fallthrough*/ case in_coord_row: { const char* expanded = accum; if (f!=l && *f>='0' && *f<='9') { while (f!=l && *f>='0' && *f<='9') *accit++ = *f++; expanded = get_cell_value(accum, accit); } else { *accit = 0; } while (*expanded) *o++ = *expanded++; continue; /*state = other;*/ } } } return o; } 

我在那里采取了一些快捷方式,因为这个语法非常简约,但它应该让你正确地知道从哪里开始。

http://ideone.com/kS7XqB上观看现场演示,这样您就可以自己玩了。 请注意,我将调试(断言)添加到get_cell_value函数,因此您不会意外地引用越界索引。

我认为可以通过表查找替换为值,只需将名称简单地删除到要替换的字符串名称中的相应值即可。

例如

 #include  #include  #include  typedef struct pair { char key[16]; int value; } Pair; int main(void){ Pair var_table[] = { { "A1", 1 }, {"B1", 2}, { "C1", 3 }};//sorted size_t size = sizeof(var_table)/sizeof(*var_table); char input[256] = "A1+B1+C1"; char outbuff[4096]; char *p; int offset = 0; printf("This -> %s\n\n", input); for(p=input;*p;){ Pair *var; char op, *opp; opp=strpbrk(p, "+-*/"); if(opp){ op = *opp; *opp = '\0';//cut string at op position } //search key(p) var = (Pair*)bsearch(p, var_table, size, sizeof(*var), (int (*)(const void *, const void *))strcmp); if(var)//find! offset += sprintf(outbuff + offset, "%d", var->value);//or store array? else offset += sprintf(outbuff + offset, "%s", "#UNKNOWN_VAR_NAME#"); if(opp){ offset += sprintf(outbuff + offset, "%c", op); p = opp + 1; } else break; } printf("to -> %s\n", outbuff); return 0; } 

每当你在C中遇到一些字符串操作问题时,你的第一直觉应该是查看string.h并看看那里有什么。 正如在这里的几个答案中所概述的那样,没有直接进行字符串替换的function,但应该可以使用strstrstrncpy来查找子字符串的出现,然后复制替换(放入新的缓冲区,以免破坏其余的原来,显然)。