2012-10-05 56 views
3

我想一些字符插入到一個字符串在C:如何插入多個字符串中的字符用C

例子:char string[100] = "20120910T090000";

我想讓它像"2012-09-10-T-0900-00"

我的代碼的東西到目前爲止:

void append(char subject[],char insert[], int pos) { 
    char buf[100]; 

    strncpy(buf, subject, pos); 

    int len = strlen(buf); 

    strcpy(buf+len, insert); 

    len += strlen(insert); 

    strcpy(buf+len, subject+pos); 
    strcpy(subject, buf); 
} 

當我把這個我第一次得到:2012-0910T090000

然而,當我把它稱爲第二次,我得到:2012-0910T090000-10T090000

任何幫助表示讚賞

+0

一個'字符字符串[20]'是太小,無法容納空終止以及2012' -09-10-T-0900-00'(不包括null的20個字符)。 –

+0

請注意,由於您未向我們展示如何調用該函數,因此我們無法知道發生了什麼問題。還要注意,'strncpy()'不能保證目標字符串的空終止,所以'strlen(buf)'不能保證給出一個有效的字符串。既然你知道長度,如果你使用'memcpy()'或'memmove()',效率會更高。將數據複製到臨時陣列然後回到原始數據並不是必須的。 –

回答

2

這裏的一些工作的代碼,這使我的輸出:

String: <<20120910T090000>> 
String: <<2012-0910T090000>> 
String: <<2012-09-10T090000>> 
String: <<2012-09-10-T090000>> 
String: <<2012-09-10-T-090000>> 
String: <<2012-09-10-T-0900-00>> 

它採用memmove(),因爲它保證被複制的字符串重疊。

#include <assert.h> 
#include <string.h> 
#include <stdio.h> 

static void insert(char *str, size_t len, char c, size_t pos) 
{ 
    memmove(&str[pos+1], &str[pos], len - pos + 1); 
    str[pos] = c; 
} 

int main(void) 
{ 
    char string[25] = "20120910T090000"; 
    // I want to make it something like "2012-09-10-T-0900-00" 
    char inschr[] = "-----"; 
    int inspos[] = { 4, 7, 10, 12, 17 }; 
    enum { NUMCHR = sizeof(inschr)/sizeof(inschr[0]) }; 
    enum { NUMPOS = sizeof(inspos)/sizeof(inspos[0]) }; 
    assert(NUMCHR == NUMPOS + 1); 
    size_t length = strlen(string); 

    printf("String: <<%s>>\n", string); 
    for (int i = 0; i < NUMPOS; i++) 
    { 
     insert(string, length, inschr[i], inspos[i]); 
     length++; 
     printf("String: <<%s>>\n", string); 
    } 
    return(0); 
} 

當然,我假設C99支持與for循環表示法。請注意,在傳統的C風格中,代碼不會佔用目標字符串的大小,因此它不能確保沒有緩衝區溢出。添加參數並進行檢查並不難,問題領域是如何指示該功能失敗。您可以使用不同的函數接口,可以在任意位置插入任意長度的字符串;它不是顯著困難......

String: <<20120910T090000>> 
String: <<2012-0910T090000>> 
String: <<2012-09-10T090000>> 
String: <<2012-09-10-T090000>> 
String: <<2012-09-10-T-090000>> 
String: <<2012-09-10-T-0900-00>> 

#include <assert.h> 
#include <string.h> 
#include <stdio.h> 

static int insert(char *str, size_t max, size_t len, char *ins, size_t pos) 
{ 
    assert(str[len] == '\0'); 
    assert(len < max); 
    size_t inslen = strlen(ins); 
    if (len + inslen + 1 >= max) 
     return -1; 
    memmove(&str[pos+inslen], &str[pos], len - pos + inslen); 
    memmove(&str[pos], ins, inslen); 
    return len + inslen; 
} 

int main(void) 
{ 
    char string[25] = "20120910T090000"; 
    // I want to make it something like "2012-09-10-T-0900-00" 
    char *insstr[] = { "-", "-", "-", "-", "-" }; 
    int inspos[] = { 4, 7, 10, 12, 17 }; 
    enum { NUMSTR = sizeof(insstr)/sizeof(insstr[0]) }; 
    enum { NUMPOS = sizeof(inspos)/sizeof(inspos[0]) }; 
    size_t length = strlen(string); 
    assert(NUMSTR == NUMPOS); 

    printf("String: <<%s>>\n", string); 
    for (int i = 0; i < NUMPOS; i++) 
    { 
     int newlen = insert(string, sizeof(string), length, insstr[i], inspos[i]); 
     if (newlen < 0) 
     { 
      printf("Oops! failed to insert [%s] into [%s]\n", insstr[i], string); 
      break; 
     } 
     length = newlen; 
     printf("String: <<%s>>\n", string); 
    } 
    return(0); 
} 
+0

'enum'而不是'const'有什麼好處? – Itsik

+0

它是[C,而不是C++](http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c/)。我可以在需要編譯時間常量的地方使用'enum'。 'const int'不是編譯時間常量。在這段代碼中,沒關係。在其他代碼中,它可能。 C99模糊了這個區別;即使大小是固定的,數組上的「const int」維也會將其變爲VLA。 –

1

你可以做這樣的事情:

char src[100] = "20120910T090000"; 
    char mask[] = "NNNN-NN-NN-C-NN-NN-NN"; 
    char dest[100] = {0}; 

    for (size_t s = 0,m = 0, d = 0; s < strlen(src) && m < strlen(mask); ++m) 
    { 
    switch (mask[m]) 
    { 
    case 'N': 
     assert(isdigit(src[s])); 
     dest[d++] = src[s++]; 
     break; 
    case 'C': 
     assert(isalpha(src[s])); 
     dest[d++] = src[s++]; 
     break; 
    default: 
     dest[d++] = mask[m]; 
     break; 
    } 
    } 
相關問題