2012-09-18 71 views
0

以下程序存儲每個單詞,然後用一些出現次數打印它們。
全球typedef聲明:函數在結構數組中搜索 - 停止條件未知

typedef struct { 
    char * word; 
    int occ; 
} 
words; 
words *data=NULL; 

我有搜索功能的問題。我創建了一個函數返回int,看起來像這樣:(max是結構數組的不斷更新的大小,這就是爲什麼我把搜索功能達到EOF後)。

int search(char *word,int max) 
{ 
    int i; 
    for(i=0; i<max; i++) 
    { 
     if(!strcmp(data[i].word,word)) return i; 
    } 
    return -1; 
} 

但是我注意到我中號應該寫具有原型搜索功能:

struct abc *find(char *word) 

所以我創建了下面的代碼:

struct words *findword(char *word) 
{ 
    struct words *ptr; 

    for (ptr = data; ptr != NULL; ptr++) {  /* IS THE STOP CONDITION OK? */ 
     if (strcmp(word, ptr->word) == 0) 
      return ptr; 
    } 
    return NULL;   

} 

我在編譯過程中收到許多錯誤:

reverse.c: In function ‘findword’:

reverse.c:73: warning: assignment from incompatible pointer type

reverse.c:73: error: increment of pointer to unknown structure

reverse.c:73: error: arithmetic on pointer to an incomplete type

reverse.c:74: error: dereferencing pointer to incomplete type

reverse.c: In function ‘main’:

reverse.c:171: error: ‘which’ undeclared (first use in this function)

reverse.c:171: error: (Each undeclared identifier is reported only once

reverse.c:171: error: for each function it appears in.)

make: * [reverse.o] Error 1


which是分配給我首先寫的搜索功能返回的int變量。 與which該錯誤很容易固定,但我不知道如何替換(解決方案與我的基本搜索功能工作):

data[which].occ++;

如何解決此問題,以便它會與我的工作新的搜索方法?


編輯

main()補充說:

int main(int argc, char **argv) 
{ 
    char *word; 
    words *temp; 
    int c,i,num; 
    /*int which;*/ 
    FILE *infile; 

    if(argc!=2) {}  
    if((infile=fopen(argv[1],"r"))==NULL) {} 
    num=0; 
    while(1) 
    { 
     c=fgetc(infile); 
     if(c==EOF) break; 
     if(!isalpha(c)) continue; 
     else ungetc(c,infile); 
     word=getword(infile); 
     word=convert(word); 
     /*which=search(word,num);*/ 
     if(findword(word)) 
     { 
      if(!(temp=realloc(data,sizeof(words)*(num+1)))) 
      {} 
      else 
       data=temp; 
      data[num].word=strdup(word); 
      data[num].occ=1; 
      num++; 
     } 
     else 
      data[which].occ++; 

     free(word); 
    } 
    sort(num-1); 
    for(i=0;i<num;i++) 
    {} 
    free(data); 
    if(fclose(infile)) 
    {} 
    return 0; 
} 

我已經離開{}代碼例如無關件。錯誤處理。


EDIT2 我所要求的上面的事,是固定的。但是,我現在遇到了seg故障。 我給一個鏈接到整個代碼,我不想把它放在一個編輯的文章,因爲它會造成一個大混亂。 Seg故障由第73行和第152行引起(strcmp無法正常工作)。希望完整的代碼更容易理解。 FULL CODE

+0

爲什麼不只需將該'int max'參數移動到一個全局變量並使用第一個版本的代碼?第二個版本將會崩潰,因爲指針將會增加並增加超過'data []'數組的末尾。 –

+0

@AlexeyFrunze我不能使用第一個函數,因爲它返回'int',我應該返回結構數組中的特定位置。 Ad.2 - 如何解決這個問題,以便指針在不斷擴大的結構數組結尾處停止遞增? –

+0

返回'&data [i]'而不是'i',那有什麼問題?除了1)引入元素計數器(或指向最後一個元素的指針)並將當前檢查的位置與該OR進行比較(我不建議這樣做)之外,您不能修復該指針,2)將特殊指示符嵌入到數據[]的最後一個元素並檢查它。 –

回答

2

的問題是與你的findword功能,讓經過的所有線路

struct words *ptr; 

這不是你換貨做什麼。您在定義結構中使用的typedef允許您不必再編寫struct。這就是爲什麼你會收到錯誤:reverse.c:73: error: increment of pointer to unknown structure。你想要的恰恰是:

words *ptr;  

接下來,循環:

for(ptr=data; //This is fine, you're assigning your local ptr to the global data. I assume that's something valid 

ptr != NULL; //That could OK too... we can loop while ptr is not NULL 
ptr++)  //This line makes no sense... 

您可能要查找如何for循環再工作,關鍵是,直到遇到一個條件你的東西遞增。 ptr ++會移動到你指向的地方,所以你將不再指向你的結構。

我要看看你的main()功能,瞭解你想實現什麼,而是基於你必須遵循的原型,我覺得最簡單的解決辦法是這樣的:

void main() 
{ 
    // init your vars 
    bool more_words_to_add = true; 
    words *ptr = NULL; 
    int i; 

    // populate your array of words 
    while(more_words_to_add) { 
     for(i = 0; i<max; i++) { 
      if(ptr = findword("word")) //if we find the word 
      ptr->occ++; //increment the number of times we found it 
      else { 
      //I don't know what you want to do here, it's not clear what your goal is. 
      //Add the new word to your array of words and set occ to 1, 
      //then increment max because there's one more word in your array? 
      } 
     } 
     //get the next word to fine, or else set more_words_to_add = false to break 
    } 
} 

如果這的解決方案類型是你希望這樣做,那麼你可以調整你的findwords功能是非常簡單的:

struct words *findword(char *word) 
{ 
    words *ptr = data; 
    if (strcmp(word, ptr->word) == 0) 
     return ptr; 
    return NULL; 
} 

編輯:爲了您的新的錯誤,我懷疑,問題是你的備忘錄RY配置,請參閱使用此結構的簡單的例子:

words *findword(char *word) 
{ 
    words *ptr = data; 
    if(strcmp(word, ptr->word) == 0) 
     return ptr; 
    return NULL; 
} 

int main(){ 
    words *ptr; 

    data = realloc(data, sizeof(words)); 
    data->word = "hello";    //DO NOT SKIP THESE LINES 
    data->occ = 0;      //DO NOT SKIP THESE LINES 

    if(ptr = findword("hello")) { 
     ptr->occ++; 
     printf("I found %d %s's\n",ptr->occ, ptr->word); 
    } 
} 

[email protected]:~> ./a.out 
I found 1 hello's 

你可以看到這裏,你需要的Alloc全球結構中的一些記憶,那麼你可以將數據存儲在它和傳遞指針給它。

編輯2:

main()代碼做到這一點:

if((ptr = findword(word))) 
{ 
    //do stuff 
} 
else 
    ptr->occ++; 

這是行不通的,因爲如果findword()失敗則返回NULL,所以在如果檢查PTR設爲NULL,然後在別人你試圖推遲NULL。如果(並且記住我真的不讀你的邏輯,這是由你),你真的想增加ptr-> OCC如果找不到一個詞,那麼你要這個:

if(findword(word)) 
{ 
    ptr = findword(word); 
    //do stuff 
} 
else 
    ptr->occ++; //increments the current ptr's occ, no new ptr was assigned. 
+0

謝謝。我已經從編譯階段刪除了所有錯誤(在您的帖子後面)。然而,現在我得到了分段錯誤,valgrind指出了兩行導致錯誤:'main()'if(strcmp(word,ptr-> word)== 0)'和'if(findword(word))'這些有什麼問題? –

+0

你的代碼越來越難以考慮。你能完成這些新問題,你能清理它到當前版本嗎?我懷疑問題是你的內存分配問題,請參閱我編輯的帖子,瞭解如何使用這個全局結構,看看是否有幫助。 – Mike

+0

我給一個鏈接到整個代碼,我不想把它放在一個編輯的文章,因爲它會造成一個大混亂。 Seg故障由線路73和152引起(strcmp不工作)。希望完整的代碼更容易理解。 [鏈接](http://pastebin.com/t3t7Cr5D) –

1

在你的程序中沒有這樣的東西struct words;有一個未命名的struct類型,以及該類型的typedef words。一致使用struct wordswords

然後您就需要

result->occ++; 

其中result是您的新的搜索函數的返回值來代替

data[which].occ++; 

+0

正如你所看到的,我正在使用'words'。我想這是錯誤的名字,那麼我應該改變什麼來忽略那些編譯錯誤? –

+0

@PeterKowalski不,你正在使用'struct words'。 – ecatmur

2
for (ptr = data; ptr != NULL; ptr++) {  
/* IS THE STOP CONDITION OK? */ 

不,你的指針只是不斷增加。在該代碼中唯一會使其成爲NULL的是整數溢出。你可以看看它指向,並看看是否爲空,如果你預設的數據區的0:

#define NUM_WORDS 100 
data = calloc(NUM_WORDS,sizeof(words)); 

或者

#define NUM_WORDS 100 
int bytes = NUM_WORDS * sizeof(words); 
data = malloc(bytes); 
memset(data,0,bytes); 

....

for (ptr = data; ptr->word != NULL; ptr++) { 

如果您不想將數據區預設爲0,那麼您必須將當前在數據區中保存的當前數量的結構傳遞給您的函數,以便知道要循環多少。