2010-11-11 35 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