2013-05-14 35 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