我正在做像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
...
感谢。
答案 0 :(得分:4)
您可能只是重用此c++ solution(通过硬编码char*
替换通用迭代器)。
我给了它一个旋转。但是,我想发出一个警告:看起来你正在尝试实现一个表达式解析器。我强烈建议你
所以你不要把自己描绘成C语言中容易出错的文本处理的尴尬角落。
编辑:我使用C ++重新编写了your C program;你可以看到它working live here。
编辑2 :纯C中C程序的另一个修正: http://ideone.com/ExnufJ 现已更新以支持迭代扩展
答案只关注纯粹的C方法:
所以,让我们开始吧。我假设了一个样本“电子表格”(它可能包含数字而不是字符串):
const char* cells[][4] = {
/* A B C D */
{ "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
函数中添加了调试(断言),因此您不会意外地引用越界索引。
答案 1 :(得分:1)
我认为可以通过表查找替换为值,只需将名称简单地删除到要替换的字符串名称中的相应值即可。
E.g
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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;
}
答案 2 :(得分:0)
任何时候你在C中遇到一些字符串操作问题,你的第一直觉应该是看string.h
并看看那里有什么。如几个答案here中所述,没有直接执行字符串替换的功能,但应该可以使用strstr
和strncpy
来查找子字符串的出现,然后复制替换(进入一个新的缓冲区,以免破坏原来的其余部分,显然)。