[英]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.