繁体   English   中英

根据输入和预定义值格式化字符串

[英]Formatting a string based on Input and predefined values

我有26个值,我正在考虑将其作为特殊符号,并且与特殊定界符“ $”一样,该值可以从$ A到$ Z。

同时我有一个预定义的模板为:

我有$ A,$ B,$ C .....

现在,我允许用户输入可以包含特殊符号和这些示例值的字符串:输入-$ ACar $ BBike $ CTruck。

然后我的输出应该是:* 我有Car,Bike,Truck ... *

到目前为止,所有特殊符号已被其值替换。

注1.如果$ A Car $ A Bike是输入值,则应取$ A,因为应该分拆汽车托座。

如果输入字符串不包含任何特殊符号,则输出中应该没有变化,输出将是$ A,$ B,$ C .....

3.如果输入从我是男人$ A杯开始,则直到$ A应该体现所有值。

我应该采取哪种方法使之成为可能?

我正在考虑对输入字符串进行strstr并将它们与我的特殊符号进行比较,并将特殊符号的位置存储在列表中,然后根据位置我想采用这些值,但我认为它不适合我。

通过使用动态字符串简化了处理。

像这样

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef struct dstr {
    size_t size;
    size_t capacity;
    char *str;
} Dstr;//dynamic string

Dstr *dstr_make(void){
    Dstr *s;
    s = (Dstr*)malloc(sizeof(Dstr));
    s->size = 0;
    s->capacity=16;
    s->str=(char*)realloc(NULL, sizeof(char)*(s->capacity += 16));
    return s;
}

void dstr_addchar(Dstr *ds, const char ch){
    ds->str[ds->size] = ch;
    if(++ds->size == ds->capacity)
        ds->str=(char*)realloc(ds->str, sizeof(char)*(ds->capacity += 16));
}

void dstr_addstr(Dstr *ds, const char *s){
    while(*s) dstr_addchar(ds, *s++);
    //dstr_addchar(ds, '\0');
}

void dstr_free(Dstr *ds){
    free(ds->str);
    free(ds);
}

void dic_entry(char *dic[26], const char *source){
    char *p, *backup, ch;

    p = backup = strdup(source);

    for(;NULL!=(p=strtok(p, " \t\n"));p=NULL){
        if(*p == '$' && isupper(ch=*(p+1))){
            if(dic[ch -'A'] == NULL)
                dic[ch -'A'] = strdup(p+2);
        }
    }
    free(backup);
}

void dic_clear(char *dic[26]){
    int i;
    for(i=0;i<26;++i){
        if(dic[i]){
            free(dic[i]);
            dic[i] = NULL;
        }
    }
}

int main(void){
    const char *template = "I have $A,$B,$C.";
    char *dic[26] = { 0 };
    char buff[1024];
    const char *cp;
    Dstr *ds = dstr_make();

    printf("input special value setting: ");
    fgets(buff, sizeof(buff), stdin);
    dic_entry(dic, buff);

    for(cp=template;*cp;++cp){
        if(*cp == '$'){
            char ch;
            if(isupper(ch=*(cp+1)) && dic[ch - 'A']!=NULL){
                dstr_addstr(ds, dic[ch - 'A']);
                ++cp;
            } else {
                dstr_addchar(ds, *cp);
            }
        } else {
            dstr_addchar(ds, *cp);
        }
    }
    dstr_addchar(ds, '\0');
    printf("result:%s\n", ds->str);

    dic_clear(dic);
    dstr_free(ds);
    return 0;
}
/* DEMO
>a
input special value setting: $ACar $BBike $CTruck
result:I have Car,Bike,Truck.

>a
input special value setting: $BBike
result:I have $A,Bike,$C.
*/

您所描述的称为宏处理器宏扩展器

您可以将符号表存储在由输入char索引的数组中。

char *symtab[256] = {0};

由于符号名称是单字母,因此可以使用strchr查找第一个'$'并检查下一个字符是否为字母( isupper() )。

对于实际的替换,除非您仅使用非常大的缓冲区并确保仅馈送少量数据,否则将需要一些精细的内存管理。

如果symtab['A'] == "Car"则可以loc = strstr(line, "$A") 然后loc-line前缀部分的长度, 2是要删除的符号名称的长度, strlen("Car")是替换的长度, strlen(loc+2)后缀部分的长度。 因此,新的字符串大小应为

char *result = malloc( (loc-line) - 2 + strlen(symtab['A']) + strlen(loc+2) + 1);

然后修补新字符串是

strcpy(result,line);
strcpy(result + (loc-line), symtab['A']);
strcpy(result + (loc-line) + strlen(symtab['A']), loc+2);

请注意,这些是strcpy 而非 strcat ,它将字符串附加在一起。 第二个和第三个strcpy调用将覆盖刚刚复制的字符串的尾部。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM