2010-07-30 360 views
1

gcc 4.4.4 c89從c字符串中刪除字符

我正在閱讀文本文件,文本文件由雙引號中的名稱組成。

"Simpson, Homer" 
etc 

但是,我想從字符串中刪除雙引號。

這是怎麼我都做到了,但我不知道它的最好的方式。

int get_string(FILE *in, char *temp) 
{ 
    char *quote = NULL; 
    /* Get the first line */ 
    fgets(temp, STRING_SIZE, in); 
    printf("temp before [ %s ]\n", temp); 
    /* Find the second quote */ 
    if((quote = strrchr(temp, '"')) == NULL) { 
     fprintf(stderr, "Text file incorrectly formatted\n"); 
     return FALSE; 
    } 
    /* Replace with a nul to get rid of the second quote */ 
    *quote = '\0'; 

    /* Move the pointer to point pass the first quote */ 
    temp++; 
    printf("temp after [ %s ]\n", temp); 
    return TRUE; 
} 

非常感謝您的任何建議,

回答

3

不,這是不行的。您正在更改參數temp,但調用函數仍然具有舊值。功能外的temp將指向開幕報價。你應該把你的緩衝區中的字符移動。

不過我建議在堆中分配緩衝區並返回一個指向它的指針,讓來電者釋放緩衝區需要的時候。這似乎是一個更清潔的解決方案。再次,這樣你就不會依賴調用者傳遞足夠大的緩衝區。

一般情況下,從文本文件中一個強大的讀取線是不是在C一項簡單的任務,其缺乏自動內存分配函數。如果可能切換到C++,我會建議嘗試更簡單的C++ getline

+1

或者,OP可以用'的memmove(溫度,溫度+ 1,strlen的(溫度+ 1)+ 1);'移動緩衝區內的字符串(而不是'temp ++;') – caf 2010-07-30 12:14:30

+0

@caf:這就是我所說的「應該將字符移動到緩衝區中」。 – Vlad 2010-07-30 12:16:12

+0

是的,我沒有針對你的評論,更多的是針對OP。 – caf 2010-07-30 12:21:24

2

所有線條看起來這樣,爲什麼不去掉簡單的第一個和最後一個字符?

quote++; // move over second char 
quote[strlen(quote)-1]='\0'; // remove last char 
+0

與我的解決方案相同,但使用相同的變量,即使字符串是const char * = P,使用相同的變量也會工作。+1,因爲回答更快 – 2010-07-30 12:01:55

+0

因爲最後一個字符實際上幾乎肯定是一個'\ n' ,因爲它是用'fgets()'讀取的(但是請注意,「second-last char」也不夠好,如果文件的最後一行沒有'\ n'!) – caf 2010-07-30 12:11:53

+0

.. 。可能會有尾隨的空間需要照顧。 – Vlad 2010-07-30 12:13:28

2

假設

字符串= 「\」 辛普森,荷馬\ 「」

然後

string_without_quotes =串+ 1;

string_without_quotes [strlen的(字符串)-2] = '\ 0';

準備好了!

2
char *foo(char *str, int notme) 
{ 
    char *tmp=strdup(str); 
    char *p, *q; 
    for(p=str, q=tmp; *p; p++) 
    { 
     if((int)*p == notme) continue; 
     *q=*p; 
     q++; 
    } 
    strcpy(str, tmp); 
    free(tmp); 
    return str; 
} 

簡單的通用刪除字符

2

不知道這是否會幫助,這是一個簡單的標記生成器,我使用

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

int token(char* start, char* delim, char** tok, char** nextpos, char* sdelim, char* edelim) { 
    // Find beginning: 
    int len = 0; 
    char *scanner; 
    int dictionary[8]; 
    int ptr; 

    for(ptr = 0; ptr < 8; ptr++) { 
     dictionary[ptr] = 0; 
    } 

    for(; *delim; delim++) { 
     dictionary[*delim/32] |= 1 << *delim % 32; 
    } 

    if(sdelim) { 
     *sdelim = 0; 
    } 

    for(; *start; start++) { 
     if(!(dictionary[*start/32] & 1 << *start % 32)) { 
      break; 
     } 
     if(sdelim) { 
      *sdelim = *start; 
     } 
    } 

    if(*start == 0) { 
     if(nextpos != NULL) { 
      *nextpos = start; 
     } 
     *tok = NULL; 
     return 0; 
    } 

    for(scanner = start; *scanner; scanner++) { 
     if(dictionary[*scanner/32] & 1 << *scanner % 32) { 
      break; 
     } 
     len++; 
    } 

    if(edelim) { 
     *edelim = *scanner; 
    } 

    if(nextpos != NULL) { 
     *nextpos = scanner; 
    } 

    *tok = (char*)malloc(sizeof(char) * (len + 1)); 

    if(*tok == NULL) { 
     return 0; 
    } 

    memcpy(*tok, start, len); 
    *(*tok + len) = 0; 


    return len + 1; 
} 

的參數是:

  • 字符*開始,(指向字符串的指針)
  • char * delim,(指向分隔符的指針u sed的打破了字符串)
  • 字符** TOK(使用&)到一個char *變量將容納托克
  • 炭基準** nextpos,(使用&)到一個char *變量的引用那將會持有最後一個令牌之後的位置。
  • 字符* sdelim,(使用&)爲char變量的引用將保存-start定界符
  • 字符* edelim,參考(使用&)爲char varaible的值,將持有的值結束分隔符

最後三個是可選的。

傳中,起始地址,該分隔符是」,並通過引用一個char *,以保持實際的中間串。

結果是一個新分配的字符串,所以你必須釋放它。

int get_string(FILE *in, char *temp) 
{ 
    char *token = NULL; 
    /* Get the first line */ 
    fgets(temp, STRING_SIZE, in); 
    printf("temp before [ %s ]\n", temp); 
    /* Find the second quote */ 
    int length = token(temp, "\"", &token, NULL, NULL, NULL) 

    // DO STUFF WITH THE TOKEN 
    printf("temp after [ %s ]\n", token); 
    // DO STUFF WITH THE TOKEN 

    // FREE IT!!! 
    free(token); 
    return TRUE; 
} 

的分詞器是一個多用途的工具,可以在一個垃圾噸的地方使用,這是一個非常小的例子。

+0

我知道這不是標記器的理想用法,但我覺得它是一個很好的工具,可以在很多情況下使用。 – 2010-07-30 12:24:26