2013-01-20 45 views
1

C初學者在這裏,我被授予家庭作業分配,我們將使用gedit設計一個程序從命令行讀取文件名並設計一個getNextWord方法。我們只需簡單地打開每個文件並返回單詞,忽略除字母數字字符以外的所有內容(並將大寫字母轉換爲低位)。我掛斷的是,我的老師給了我們strdup()函數來幫助我們以及isspace,alnum等等。無論如何,在查詢本網站上的strdup()以及C基礎知識和網站和其他人一定有我不理解的東西。我的程序編譯(我使用gcc -Wall -pedantic -std = c99 words.c -o words),並且它僅編譯一個警告,即strdup()被隱式使用。在同一個目錄下運行一些文本文件的程序,它會打印出gobbly gook,好像它跑出堆的邊界,然後給出分段錯誤(核心轉儲)。我以爲我也給了它正確的檢查,比如在返回指針的strdup之前在字符數組的末尾加上\ 0等,這是我的代碼;我不期待任何人爲我做我的事,也許觀察會有幫助,因爲我整天研究並找不到問題。感謝您閱讀本(它沒有顯示,但我包括標準輸入輸出,文件stdlib.h,string.h中,文件ctype.hC使用strdup()等從文件中讀取/打印單詞

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#define MAX_WORD_SIZE 256 


char* getNextWord(FILE* fd) 
{ 

    int index = 0; 
    int c; 

    char str[MAX_WORD_SIZE]; 

    while((c = fgetc(fd)) != EOF){ 

     c = fgetc(fd); 

     if (isspace(c)){ 
      str[index] = '\0'; 
      return (char*) strdup(str); 
     } 

     if (((index+1) != (MAX_WORD_SIZE-1)) && (isalnum(c))){ 
      c = tolower(c); 
      str[index] = c; 
      index++; 
     } 
     else { 
      index++; 
      str[index] = '\0'; 
      return (char*) strdup(str); 
     } 

    } 

    return NULL; 
} 

int main(int argc, char* argv[]) 
{ 
    char** current = argv; 
    char* heapedString = NULL; 

    while (*current) 
    { 
     char* filename = *current; 
     FILE* fd = fopen(filename, "r"); 
     if (fd == NULL) 
     { 
      fprintf(stderr,"can't read the file\n"); 
      exit(-1); 
     } 

     while ((heapedString = getNextWord(fd)) != NULL) 
     { 
      heapedString = getNextWord(fd); 
      printf("%s\n", heapedString); 
      free(heapedString);   
     } 
     fclose(fd); 
     current++; 

    } 
    return 0; 
} 

回答

1

你在每次迭代中兩次調用函數fgetc - 曾經在一段時間()條件和右。之後,您還呼籲getNextWord時犯同樣的錯誤

4

也許是因爲你放棄所有其他的字符和文字你有相同類型的錯誤在這兩個田地:

while((c = fgetc(fd)) != EOF){ 

    c = fgetc(fd); 

    .... 
} 

你應該只每個循環調用一次fgetc(或getNextWord),你應該這樣做:

while((c = fgetc(fd)) != EOF){ 
    .... 
} 

或者這樣:

while(1){ 
    c = fgetc(fd); 
    if (c == EOF) break; 
    .... 
} 

但不是兩個

3

組合這只是一種預感,但我相信下面兩行是錯誤的原因。

while((c = fgetc(fd)) != EOF){ 
c = fgetc(fd); 

在每次使用時,內部文件位置指示符會前進到下一個字符。所以它正在通過while循環調用。這可能會搞亂你想要的結果。

看看這裏找到的代碼,並注意使用do while代替。祝你好運!
http://www.cplusplus.com/reference/cstdio/fgetc/

1

至於問題的strdup部分的隱式聲明:strdup,像許多其他常用功能,是不是C99標準庫的一部分。如果您查看man strdup並查看「glibc的特性測試宏要求」部分,則在加入庫之前,您會看到對#define有什麼要求。例如:

#define _POSIX_C_SOURCE 200809L 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    const char *foo = "foo"; 
    char *bar = strdup(foo); 
    puts(bar); 
    free(bar); 
} 

你會遇到這個,如果你想使用POSIX功能,並在同一時間使用-std = C99選擇留爲ISO C99兼容成爲可能。

0

小問題,但爲什麼您使用

if (((index+1) != (MAX_WORD_SIZE-1)) && (isalnum(c))) 

爲你的檢查?從索引中刪除+1就足夠了,我想。對於我這個任務的代碼我使用

if (isalnum(c) && (j <= (MAX_WORD_SIZE - 1))) 

,並根據需要通過分配AFAICT它的工作原理正是(很明顯,我有J所示我的「索引」和順序無關)

你想要在main中添加一個檢查來查看heapedString [0] =='\ 0'是否也是,否則你會得到大量空行打印。雖然這仍然可以滿足作業,但最好不要打印出來。

相關問題