2013-05-14 58 views
0

我有26个值,我正在考虑为特殊符号并且与特殊的分隔符“$”一样,值可以从$ A到$ Z。基于输入和预定义值格式化字符串

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

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

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

那么我的输出应该是:* 我有汽车,自行车,汽车... *

现在所有特殊符号已取代它的价值。

注意1.if $ A汽车$自行车是输入值,那么它应该需要$ A,因为汽车休息应该放弃。

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

3,如果输入开始为我是男士$ A玻璃然后直到$ A所有的价值都应该放弃。

我应该采取哪种方法来实现这一点?

我想办的strstr输入字符串和比较这些与我的特殊符号和保存特殊符号的位置列表,然后按位置我想到取的值,但我不不要以为它会为我工作。

回答

1

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

这样

#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. 
*/ 
+0

上述程序的输出根据输入值不同而不同,它应该输出相应的值。例如 - 当输入字符串为 - $ ACar $ BBike $ CPen或$ CPen $ ACar $时,输出应该没有差异BBike.It这两个输入的价值$ A,$ B,$ C是一样的。 – 2013-05-16 04:10:53

+0

@Astro它会是一样的(不管顺序如何),但也有任何问题? – BLUEPIXY 2013-05-16 08:04:09

+0

它应该独立于order.if你输入** $ AAA $ ACAR $ BBIKE **那么$ A的值应该是AAA,$ B应该是Bike ** $ ACAR **应该被丢弃。并且在** AAA $ ACAR $ BBIKE ** ** AAA **的情况下应该丢弃。 – 2013-05-16 11:49:10

0

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

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

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

通知这些strcpystrcat其中追加字符串连接在一起。第二个和第三个strcpy调用覆盖刚刚复制的字符串的尾部。

+0

我有一个阵列,其将被存储的特殊符号**炭AR [26] [3];它的值为$ A,$ B .....并且在行中我正在执行strstr(line,ar(index),,,然后将该位置保存在列表中。但不知道如何收集值?以及在你的算法中,你是如何得到特殊符号的实际值的? – 2013-05-14 06:08:08

+0

我会用常规的ascii值进行索引,但它确实浪费空间。用你的方式,你必须通过加入和减去'A'来转换为ascii/''$%c =%[^ $] $%c =%[^ $] $%c =%[^ $] $%c = %[^ $]“'。 – 2013-05-14 06:22:22

+0

确定....但直到现在还没有得到你如何采取特殊符号的值? – 2013-05-14 06:24:07