2013-04-07 91 views
3

我正在使用以下代碼掃描文本文件中的每個單詞,將其放入一個變量中,然後在移至下一個單詞之前對其進行一些操作。這工作正常,但我試圖刪除所有不屬於A-Z/a-z.的字符,例如,如果輸入"he5llo"我希望輸出爲"hello"。如果我不能修改fscanf來做到這一點,有沒有辦法對變量進行一次掃描?謝謝。刪除fscanf字符串中的特殊字符C

while (fscanf(inputFile, "%s", x) == 1) 
+0

那'fscanf'有一個很大的問題:它是潛在的緩衝區溢出。當你有'char x [100]'時,你應該總是使用'fscanf(inputFile,「%99s」,x)''。 – hyde 2013-04-07 17:01:24

回答

3

的所有字符,您可以給x到這樣的功能。首先簡單版本的理解緣故

// header needed for isalpha() 
#include <ctype.h> 

void condense_alpha_str(char *str) { 
    int source = 0; // index of copy source 
    int dest = 0; // index of copy destination 

    // loop until original end of str reached 
    while (str[source] != '\0') { 
    if (isalpha(str[source])) { 
     // keep only chars matching isalpha() 
     str[dest] = str[source]; 
     ++dest; 
    } 
    ++source; // advance source always, wether char was copied or not 
    } 
    str[dest] = '\0'; // add new terminating 0 byte, in case string got shorter 
} 

它會經過就地字符串,複製匹配isalpha()測試,字符,跳繩從而消除那些不。爲了理解代碼,重要的是要認識到C字符串只是char數組,字節值0表示字符串的結尾。另一個重要的細節是,在C數組和指針中有很多(不是全部)方法,所以指針可以像數組一樣被索引。此外,這個簡單的版本將會重寫字符串中的每個字節,即使字符串實際上沒有改變。


然後,功能更全面的版本,它使用作爲參數傳遞過濾功能,只會做存儲器的寫入如果str變化,並返回指針str最喜歡的庫字符串函數做:

char *condense_str(char *str, int (*filter)(int)) { 

    int source = 0; // index of character to copy 

    // optimization: skip initial matching chars 
    while (filter(str[source])) { 
    ++source; 
    } 
    // source is now index if first non-matching char or end-of-string 

    // optimization: only do condense loop if not at end of str yet 
    if (str[source]) { // '\0' is same as false in C 

    // start condensing the string from first non-matching char 
    int dest = source; // index of copy destination 
    do { 
     if (filter(str[source])) { 
     // keep only chars matching given filter function 
     str[dest] = str[source]; 
     ++dest; 
     } 
     ++source; // advance source always, wether char was copied or not 
    } while (str[source]); 
    str[dest] = '\0'; // add terminating 0 byte to match condenced string 

    } 

    // follow convention of strcpy, strcat etc, and return the string 
    return str; 
} 

實施例濾波器功能:

int isNotAlpha(char ch) { 
    return !isalpha(ch); 
} 

調用示例:

char sample[] = "1234abc"; 
condense_str(sample, isalpha); // use a library function from ctype.h 
// note: return value ignored, it's just convenience not needed here 
// sample is now "abc" 
condense_str(sample, isNotAlpha); // use custom function 
// sample is now "", empty 

// fscanf code from question, with buffer overrun prevention 
char x[100]; 
while (fscanf(inputFile, "%99s", x) == 1) { 
    condense_str(x, isalpha); // x modified in-place 
    ... 
} 

參考:

int isalpha (int c);手冊:

檢查c是否是字母文字。
返回值
如果確實c是字母字母,則值爲零(即爲真)。零(即,假)否則

+1

@RandyHoward如果你認爲它的錯誤建議應該如何迴應相反..海德不知道OP是否要求作業或自我學習的目的。海德只是幫忙。 – 2013-04-07 17:03:26

+0

@hyde我想建議,總是解釋你的代碼,以便它可以幫助OP更好地.. – 2013-04-07 17:06:16

+0

回答乾杯,雖然我不完全理解你給的例子,所以我會努力使用它爲我的做法。 – user2254988 2013-04-07 17:27:10

0

可以使用isalpha()功能檢查包含到字符串

0

scanf家庭功能不會這樣做。您必須遍歷字符串並使用isalpha來檢查每個字符。通過向前複製字符串的末尾來「刪除」memmove中的字符。

也許scanf可以做到這一點。在大多數情況下,scanf和朋友會將任何非空白字符推回輸入流,如果它們不匹配。

本示例使用scanf作爲流上的正則表達式過濾器。使用*轉換修飾符意味着不存在無效模式的存儲目標;它只是被吃掉了。

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

int main(){ 
    enum { BUF_SZ = 80 }; // buffer size in one place 
    char buf[BUF_SZ] = ""; 
    char fmtfmt[] = "%%%d[A-Za-z]"; // format string for the format string 
    char fmt[sizeof(fmtfmt + 3)]; // storage for the real format string 
    char nfmt[] = "%*[^A-Za-z]";  // negated pattern 

    char *p = buf;        // initialize the pointer 
    sprintf(fmt, fmtfmt, BUF_SZ - strlen(buf)); // initialize the format string 
    //printf("%s",fmt); 
    while(scanf(fmt,p) != EOF     // scan for format into buffer via pointer 
     && scanf(nfmt) != EOF){     // scan for negated format 
     p += strlen(p);       // adjust pointer 
     sprintf(fmt, fmtfmt, BUF_SZ - strlen(buf)); // adjust format string (re-init) 
    } 
    printf("%s\n",buf); 
    return 0; 
} 
0

我正在研究一個類似的項目,所以你很好!將單詞分解成單獨的部分。

空格是不是一個問題,與CIN每個字 可以使用

if(!isPunct(x)) 

增加1的指數,而新的字符串添加到一個臨時串座。 您可以像數組一樣選擇字符串中的字符,因此找到這些非字母字符並存儲新字符串很容易。

string x = "hell5o"  // loop through until you find a non-alpha & mark that pos 
for(i = 0; i <= pos-1; i++) 
            // store the different parts of the string 
string tempLeft = ... // make loops up to and after the position of non-alpha character 
string tempRight = ... 
1

luser droog答案會工作,但在我看來,它是比必要的更復雜。

FOI您簡單的例子,你可以試試這個:

while (fscanf(inputFile, "%[A-Za-z]", x) == 1) { // read until find a non alpha character 
    fscanf(inputFile, "%*[^A-Za-z]")) // discard non alpha character and continue 
} 
+1

是的。那更好。 +1 – 2013-04-07 20:20:31

相關問題