2010-11-11 26 views
3

我正在做一個閱讀書籍的家庭作業。首先讀入一行,並在該行指向一個指針。然後一個段落函數讀取行並將它們的地址存儲到一個指針數組中。現在,我正在閱讀一章(下一行被識破的一段被破壞)。它應該調用get_paragraph()並存儲段落的地址,直到出現新章節。解析章節時的Coredump

新的篇章是在本書,在該行的第一個字符是不是空格唯一的一次。我認爲這是我的代碼有問題。到此爲止的所有功能都能正常工作。我希望我已經提供了足夠的信息。代碼在啓動時編譯但核心轉儲。

我是一名學生,學習的,所以請善待。謝謝。

char*** get_chapter(FILE * infile){ 

    int i=0; 

    char **chapter[10000];//an array of pointers 
    // Populate the array 
    while(chapter[i]=get_paragraph(infile)) { //get address store into array 
     if(!isspace(**chapter[0])){ //check to see if it is a new chapter<---problem line? 
     // save paragraph not used in chapter using static to put into next chapter 
     break; 
     } 
     i++;//increment array 
    } 
    //add the null 
    chapter[++i]='\0';//put a null at the end to signify end of array 
    //Malloc the pointer 
    char**(*chap) = malloc(i * sizeof(*chap));//malloc space 
    //Copy the array to the pointer 
    i=0;//reset address 
    while(chapter[i]){//while there are addresses in chapter 
     chap[i] = chapter[i++];//change addresses into chap 
    } 
    chap[i]='\0';//null to signify end of chapter 
    //Return the pointer 
    return(chap);//return pointer to array 
    } 

對於那些誰寧願看到沒有評論:

char*** get_chapter(FILE * infile){ 

    int i=0; 

    char **chapter[10000]; 
    while(chapter[i]=get_paragraph(infile)) { 
     if(!isspace(**chapter[0])){ 
     break; 
     } 
     i++; 
    } 
    chapter[++i]='\0'; 
    char**(*chap) = malloc(i * sizeof(*chap));//malloc space 
    i=0; 
    while(chapter[i]){ 
     chap[i] = chapter[i++]; 
    } 
    chap[i]='\0'; 
    return(chap); 
    } 
+0

我不知道爲什麼有人需要看到你的代碼*沒有*評論。我們需要看到的是格式正確的代碼。粘貼後,使用1010按鈕將整個代碼塊縮進四個空格。然後修復縮進的其餘部分,這樣纔有意義。如果你在一個只使用空格字符**的編輯器中縮進它,那麼在將它粘貼到SO之前,然後使用1010按鈕將其格式化爲代碼,這將更容易。 – RBerteig 2010-11-11 06:43:43

+0

謝謝,在我的代碼中,我的代碼中實際上有一個#define CHAPTERLIM,但通過這個數字,所以不必解釋它,但我現在編輯了這篇文章。所以它看起來像char **章節[CHAPTERLIM]; – pisfire 2010-11-11 06:45:12

+1

這是我在一段時間裏看到的更好的作業問題之一。我讓你的第一段更容易閱讀。 – 2010-11-11 06:49:11

回答

1

我可以建議你使用for循環,而不是while S'如果空間不足,你需要停下來,所以你不妨使用適當的結構。

我懷疑你有這個代碼中的錯誤:

while(chapter[i]=get_paragraph(infile)) { 
    if(!isspace(**chapter[0])){ 
    break; 
    } 
    i++; 
} 
chapter[++i]='\0'; 

首先,它不應該是chapter[i],而不是chapter[0]?您想知道chapter[i]處的指針是否指向空格,而不是chapter中的第一個指針。所以這可能會無限循環 - 因此需要一個for循環,所以你不會意外地永遠循環。

其次,你在chapter[++i]分配在同時段結束遞增i,然後再次。 i在while條件中斷之前已經被最終循環執行遞增,所以它已經是正確的使用位置。++i遞增之前產生的價值,所以大概你打算在這裏有i++,所以它會增加產生當前值i。無論哪種方式,我們中的一個人對你的意思感到困惑,所以也許只是爲了清晰起見將增量放在單獨的行上。編譯器將整理出任何可用的優化。

最後(我可能在這裏錯了)爲什麼你將值設置爲'\0'?這是一個空字符,不是嗎?但是你的數組是指針。我認爲,空指針將是0,而不是'\0'。如果我是對的,如果'\0'與空指針產生相同的一組零,那麼你可能仍然會擺脫它。

+0

''\ 0''是一個整數常量,值爲零,就像0和0LL一樣,我不記得C的轉換對零指數類型的整數常量的更精細的點,以及具有int類型的字符文字如何影響這一點,但我強烈懷疑它的處理方式與0相同,0L或0LL,而不是僅僅產生相同的一組零。這就是說,你覆蓋了我注意到的所有東西,並且將會回答。:) – 2010-11-11 07:31:26

+0

@Roger Pate:這是正確的,在C中' \ 0''的行爲與'0'完全相同,包括使用空指針常量的能力,唯一的區別在於它傳遞給人類讀取代碼的含義。 – caf 2010-11-11 10:49:39

0

它不應該是:

if(!isspace(**chapter[i])){ 

每個chapter[i]是一個指針的指針到char,這char是每章中的第一個字。所以**chapter[i]代表i章中的第一個字符。使用chapter[0]只會看第一章。

+0

我不知道,我只想檢查行中的第一個元素。如果[我]在那裏,我會穿過它,不是嗎? – pisfire 2010-11-11 06:49:45

+0

如果你有一個字符串'char * foo'並且使用'* foo'去除它,你會得到字符串中的第一個字符。 '**章節[i]'會給你每個'章節'的第一個'char'。你現在的代碼只看第一章。 – 2010-11-11 06:53:34

0

您是否嘗試過單在gdb步進雖然,偶爾傾銷局部變量查看當前的狀態?這是學習的好方法。您可能需要添加一些額外的中間變量「信息機」會自動轉儲以及(指向當前XXX,XXX是層次結構中的各種物品)

我假設一個GNU環境:

% gcc -g homework.c -o hw 
% gdb hw 
(gdb) b 10 
(gdb) r 
(gdb) info locals 
(gdb) n 
(gdb) info locals 
... 

替換「10」與附近的功能的開始的合適的行數。

+0

我已經通過了洞察力,這就是爲什麼我認爲問題是檢查段落中的第一個元素,但我不是100%確定。 – pisfire 2010-11-11 06:51:13

+0

什麼OS/dev kit/IDE? – Roboprog 2010-11-11 06:54:06

+0

cygwin,unix系統 – pisfire 2010-11-11 07:03:27

2

評論在線。

char*** get_chapter(FILE * infile) { 
    int i=0; 

    // This is a zero length array! 
    // (The comma operator returns its right-hand value.) 
    // Trying to modify any element here can cause havoc. 
    char **chapter[10,000]; 

    while(chapter[i]=get_paragraph(infile)) { 
    // Do I read this right? I translate it as "if the first character of 
    // the first line of the first paragraph is not whitespace, we're done." 
    // Not the paragraph just read in -- the first paragraph. So this will exit 
    // immediately or else loop forever and walk off the end of the array 
    // of paragraphs. I think you mean **chapter[i] here. 
    if(!isspace(**chapter[0])){ 
     break; 
    } 
    i++; 
    } 

    // Using pre-increment here means you leave one item in the array uninitialized 
    // which can also cause a fault later on. Use post-increment instead. 
    // Also '\0' here is the wrong sort of zero; I think you need NULL instead. 
    chapter[++i]='\0'; 

    char**(*chap) = malloc(i * sizeof(*chap)); 
    i=0; 
    while(chapter[i]) { 
    // This statement looks ambiguous to me. Referencing a variable twice and 
    // incrementing it in the same statement? You may end up with an off-by-one error. 
    chap[i] = chapter[i++]; 
    } 

    // Wrong flavor of zero again. 
    chap[i]='\0'; 
    return(chap); 
} 
+0

「我讀過這個嗎?我把它翻譯爲」如果第一段第一行的第一個字符不是空格,我們就完成了。不是剛剛讀到的段落 - 第一章「你的假設是正確的 – pisfire 2010-11-11 06:57:43

+0

Eep。我的意思是」第一段「,而不是」第一章「,編輯 – 2010-11-11 07:59:59