2016-02-14 88 views
-1

比方說,我有一個包含以下文本字符串:C語言如何切出一個字符串的一部分

#Line1 Hello, today I ate 3 crackers for dinner 
#Line2 and 4 crackers with some soup for lunch. 
#Line3 For breakfast tomorrow, I plan on eating 
#Line4 bacon, eggs, and ham. 

,我想從一個子繩剪斷的部分到另一個子,爲例如,從"#Line3"\n得到以下的輸出:

#Line1 Hello, today I ate 3 crackers for dinner 
#Line2 and 4 crackers with some soup for lunch. 
#Line4 bacon, eggs, and ham. 

(基本上只是切出一切從#Line3\n並在本質拆除整個3號線)

我讀過這可以用功能memmove完成,但一直沒能弄清楚如何正確地做到這一點。然而,如果任何人有一個解決方案,不涉及移位,當然這將是同樣的讚賞。

這是我到目前爲止有:

int str_cut(char *str, char *begin, int len) 
{ 
    int l = strlen(str); 
    if (strlen(begin) + len > l) len = l - begin; 
    memmove(str + strlen(begin), str + begin + len, l - len + 1); 
    return len; 
} 

這是迄今爲止相當遙遠在完成我想要的東西,因爲它依賴於知道什麼需要的長度被切出來,我希望它做的是2個字符之間切出,與我前面的例子一起去切「line3」和\n

+0

我想你會更好的閱讀http://www.peope.net/old/regex.html –

+0

如果你包含你的代碼,我們可能會指出你的錯誤。 – usr2564301

+0

會做,一會兒。我沒有包括任何東西的原因是我所擁有的真的很微不足道,但堅持下去。 –

回答

0

很容易使用的memmove:

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

char * 
strfilter(const char *str, const char *substr) 
{ 
    char *res = strdup(str), *ptr = NULL; 
    size_t len = 0; 

    if (!res) 
     return NULL; 

    ptr = strstr(res, substr); 

    if (!ptr) 
    { 
     free(res); 
     return NULL; 
    } 

    len = strlen(ptr) - strlen(substr); 
    memmove(ptr, ptr + strlen(substr), len); 
    memset(ptr + len, 0, strlen(ptr + len)); 

    return res; 
} 

char * 
strfilter2(const char *str, const char *start, const char *end) 
{ 
    char *res = strdup(str), *ptr1 = NULL, *ptr2 = NULL, *tmp = NULL; 
    size_t len1 = 0, len2 = 0; 

    if (!res) 
     return NULL; 

    ptr1 = strstr(res, start); 
    ptr2 = strstr(res, end); 

    if (!ptr1 || !ptr2) 
     return NULL; 

    if (ptr1 > ptr2) 
    { 
     tmp = ptr2; 
     ptr2 = ptr1; 
     ptr1 = tmp; 
     tmp = end; 
     end = start; 
     start = tmp; 
    } 

    len1 = strlen(start); 
    len2 = strlen(ptr2); 
    memmove(ptr1 + len1, ptr2, len2); 
    memset(ptr1 + len1 + len2, 0, strlen(ptr1 + len1 + len2)); 

    return res; 
} 

int 
main(void) 
{ 
    const char *str = "Hello, today I ate 3 crackers for dinner\n" 
         "and 4 crackers with some soup for lunch.\n" 
         "For breakfast tomorrow, I plan on eating\n" 
         "bacon, eggs, and ham.\n"; 
    char *res = strfilter2(str, "and 4 crackers with some soup for lunch.\n", "bacon, eggs, and ham.\n"); 

    if (!res) 
    { 
     perror("strfilter2()"); 
     return 1; 
    } 

    puts(res); 
    free(res); 

    return 0; 
} 

功能只是認爲,要刪除,並用後,在於這一切覆蓋它的子字符串,然後將其歸零出的剩餘字符串。

編輯: 增加strfilter2消除兩個子串之間的內容。

+0

我可以用這個工作。謝謝 –

+0

我怎麼能修改這個,以便不是切割整條線而是切割2個子串之間的所有東西?對於我正在做的事情,我不一定會知道整個行 –

+0

已編輯。嘗試strfilter2。 – anon

0

之間的一切使用memcpy可以兩個部分複製到兩個緩衝器中,然後將它們用strcat CONCAT。

Get a substring of a char*

0

要切出一部分字符串,您需要找到 - 當然 - 首先要剪切的部分的開始和結束標記。對於您可以使用strstr.然後就(結束標誌後的所有內容)複製其餘部分在哪裏找到起始記號的地方:

char * cut_between(
    char * const str, 
    char const * const from, 
    char const * const to) { 
    char * const startMark = strstr(str, from); 
    if (! startMark) { 
    return NULL; 
    } 
    char * const endMark = 
    strstr(startMark+strlen(from), to); 
    if (endMark) { 
    strcpy(startMark, endMark+strlen(to)); 
    return startMark + strlen(startMark) + 1; 
    } else { 
    *startMark = '\0'; 
    return startMark + 1; 
    } 
} 

成功時上述函數返回一個指針超出了所產生的結束串。這是緩衝壓實有用,如:

int main() { 
    char * const input = malloc(400); 
    fgets(input, 400, stdin); 
    char const * const end = 
    cut_between(input, "from", "to"); 
    if (end) { 
    char const * const result = 
     realloc(input, end - input); 
    puts(result); 
    // OMG missing free(s), well ... OK for this simple test. 
    } 
    return 0; 
} 

(Live on ideone)

請注意,上面的測試缺少的錯誤檢查。在生產代碼中必須添加這些代碼。

相關問題