字符串替换件 [英] replacing pieces of string

查看:113
本文介绍了字符串替换件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做类似Excel中,我有这样的事情:

  1 2 3
A1 B1 C1

它取代了指定的内容,其中A1取代1的内容的内容。
B1取代了2内容...等...

我使用的是多维数组,我真的很喜欢这样的事情:

  INT偏移= 0,readCharCount;
    而(sscanf的(MATRIS [I] [C] +偏移,%C%D%* C%N,&安培;山坳,和放大器; linha,&安培; readCharCount)== 2){
        //的printf(%C,%d个\\ N,山坳,linha);
        //的strcpy(MATRIS [I] [C],MATRIS [linha-​​1] [山口 - 'A']);        胶印+ = readCharCount;
      //输出({%C,%D},山坳,linha);
      //的printf(\\ n);
  }

但是,当我有A1 + B1 + C1和另外的事情,我不能代替的总含量,因为其他的引用将被删除......

所以,在细胞内,A1 + B1 + C1,我想改变为B1指定的内容....我想有这样的:

 此 - > A1 + B1 + C1至 - > 1 + 2 + 3

...

感谢。


解决方案

您可能只是重复使用该<一个href=\"http://stackoverflow.com/questions/17112494/how-to-expand-environment-variables-in-ini-files-using-boost/17128601#17128601\">c++解决方案(通过硬编码的char * 不是替换通用迭代器)。

我给它一个旋转。不过,我想给一个警告:它看起来像你想实现一个前pression解析器。我强烈建议你为


  • handroll一个(递归下降)分析器

  • 使用柔性/野牛(或法/ yacc的)

所以你不要画在自己容易出错的文本处理C的一个尴尬的角落。


  

修改我重写 C程序使用C ++;你可以看到它的此处工作现场。


  
  

修改2:纯C C程序的另一种修正: 的http:/ /ideone.com/ExnufJ 更新,现在支持迭代扩展,太


答案只是关注自身与纯C的方法:

那么,让我们开始吧。我以为一个样本的S preadsheet(它可能包含数字而不是字符串):

 为const char *细胞[] [4] = {
    /* A B C D */
    {的,懒惰,牛,跳楼} / * 1 * /
    {超过,中,快速,棕色} / * 2 * /
    {纸,套餐,捆绑,向上} / * 3 * /
    {与,银,白,冬天} / * 4 * /
    {说,融,狐狸精,弹簧} / * 5 * /
};

使用只有两个助手:

 为const char * get_cell_value(为const char * coordinate_b,为const char * coordinate_e);
字符* expand_cell_references(为const char *楼为const char * const的L,字符* O); / *魔引擎* /

我们可以写出下面的演示程序:

  INT的main()
{
    为const char []中=的C2 D2 C5 D1 A2 B2 B1的狗!    烧焦出[1024] = {0};
    expand_cell_references(IN,IN +的strlen(中),淘汰);
    看跌期权(出); / *敏捷的棕色狐狸跳过了懒狗! * /    返回0;
}

打印出公知的测试短语按照注释。现在, get_cell_value 是非常简单的:

 为const char * get_cell_value(为const char * coordinate_b,为const char * coordinate_e)
{
    为size_t山坳= 0,行= 0;
    为const char *它;
    对于(IT = coordinate_b;!它= coordinate_e ++吧)
    {
        如果(*它&GT; ='A'和;&放大器; *它&LT; ='Z')
            COL = 26 * COL +(*吧 - 'A');
        如果(*它&GT; ='0'和;&放大器; *它&LT; =9)
            行= 10 *行+(*吧 - '0'); / *或使用的atoi和朋友* /
    }
    行 - ; / * 1,基于行NUMS在Excel * /    回报细胞[行] [COL]; / *在Excel中1为基础的索引* /
}

expand_cell_references 是稍微有点复杂,是一个简单的DFA解析器:

 的char * expand_cell_references(为const char *楼为const char * const的L,字符* O)
{
    枚举parser_state {
        其他,
        in_coord_col,
        in_coord_row
    }状态=等;    为坐标/ *临时存储被解析:* /
    焦炭ACCUM [16] = {0};
    字符* accit = ACCUM;
    而(F!= 1)
    {
        开关(州)/ *假人,过渡的fallthrough订单流,现在* /
        {
            其他情况:
                *(accit = ACCUM)= 0; / *复位累加器* /
                而(F = L&安培;!&安培;!(* F&GT; ='A'和;&放大器; * F&LT; ='Z'))
                    *○++ = *˚F++;
                / * * fallthrough /
            案例in_coord_col:
                而(F = L&安培;!&放大器; * F&GT; ='A'和;&放大器; * F&LT; ='Z')
                    * accit ++ = *˚F++;
                / * * fallthrough /
            案例in_coord_row:
                {
                    为const char *扩大= ACCUM;
                    如果(F = L&放大器;!&放大器; * f是氟烃基; ='0'和;&放大器; * F&下; ='9')
                    {
                        而中(f = L&放大器;!&放大器; * f是氟烃基; ='0'和;&放大器; * F&下; ='9')
                            * accit ++ = *˚F++;
                        扩展= get_cell_value(ACCUM,accit);
                    }
                    其他
                    {
                        * accit = 0;
                    }
                    而(*展开)
                        *○++ = *扩大++;
                    继续; / *状态=等; * /
                }
        }
    }
    返回O;
}

我花了一些快捷键那里,因为这个语法是如此的简约,但它应该给你从哪里开始正确的想法。


  

请参阅现场演示这里 http://ideone.com/kS7XqB 等等你可以用它自己玩。请注意,我说的调试(断言)在 get_cell_value 功能,所以你不小心引用越界的索引。


i'm doing something like excel, i have something like this:

1         2           3
A1        B1          C1

where it replaces the content for specified content, where A1 replaces the content for 1. B1 replaces the content of 2...and etc...

i'm using a multidimensional array, and i do the things like this:

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");
  }

But when i have A1+B1+C1 and another things, i cant replace the total content, because other references will be removed....

So, at the cell, A1+B1+C1, i wanna change B1 for the content specified....i wanna have like this:

This -> A1+B1+C1

to -> 1+2+3

....

Thanks.

解决方案

You might just reuse this c++ solution (replacing the generic iterators by hardcoding char* instead).

I gave it a whirl. However, I wish to give a warning: it looks like you're trying to implement an expression parser. I'd strongly advise you to either

  • handroll a (recursive descent) parser
  • use flex/bison (or lex/yacc)

so you don't paint yourself in an awkward corner of error-prone text-handling in C.

Edit: I rewrote your C program using C++; you can see it working live here.

Edit 2: Another fixup of your C program in pure C: http://ideone.com/ExnufJ updated to support iterative expansions now, too

The answer just concerns itself with the pure C approach:

So, let's get started. I assumed a sample "spreadsheet" (it could contain numbers instead of strings):

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 */
};

Using just two helpers:

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*/

we can write the following demo program:

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;
}

which prints the well-known test phrase as per the comment. Now, get_cell_value is really simple:

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 */
}

And expand_cell_references is slightly more involved, being a simple DFA parser:

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;
}

I took some shortcuts there, because this grammar is so minimalist, but it should give you a proper idea of where to start.

See a live demo here http://ideone.com/kS7XqB so you can play with it yourself. Note that I added debugging (asserts) to the get_cell_value function so you don't accidentally reference out-of-bounds indexes.

这篇关于字符串替换件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆