Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 由于使用fgets()将文件中的行读取到结构数组中而导致的分段错误_C_Arrays_Struct_Segmentation Fault - Fatal编程技术网

C 由于使用fgets()将文件中的行读取到结构数组中而导致的分段错误

C 由于使用fgets()将文件中的行读取到结构数组中而导致的分段错误,c,arrays,struct,segmentation-fault,C,Arrays,Struct,Segmentation Fault,我目前正在学习C语言,需要一些代码方面的帮助 假设有一个名为“books.txt”的文件,它在文件的新行中包含多本书的名称。我正试图抓取每本书的名字,以便在我的程序的其余部分使用 为此,我创建了以下内容: struct bookData { // This is my struct to encapsulate book information char name[50]; // Name of book // Other struct variable // Ot

我目前正在学习C语言,需要一些代码方面的帮助

假设有一个名为“books.txt”的文件,它在文件的新行中包含多本书的名称。我正试图抓取每本书的名字,以便在我的程序的其余部分使用

为此,我创建了以下内容:

struct bookData { // This is my struct to encapsulate book information
     char name[50]; // Name of book
     // Other struct variable
     // Other struct variable
};
现在我需要获得每本书的名称,并将它们放入结构数组中。下面是我如何做到这一点的

struct bookData booksList[numBooks]; // numBooks is the number of books in "books.txt"

int i;
for(i = 0; i < numBooks; i++) {
     fgets(booksList[i].name, 50, books);
     // Books is the "books.txt" file that was opened for reading
}
如果没有for循环,就不会发生错误,代码可以正常运行并打印书籍的名称

我试图理解为什么我的代码中会出现错误。如果有人能给我一些关于如何修正错误的建议,我将不胜感激。提前感谢您抽出时间阅读/回答我的问题

编辑:numBooks本质上是“books.txt”文件中的行数。这就转化为这个问题的书的数量。numBooks是使用以下代码计算的:

char c; 
int numBooks; 
while((c = fgetc(books)) != EOF) { 
    if(c == '\n') { 
         numBooks++; 
    } 
}

编辑#2:谢谢大家的帮助

以下代码是错误的,可以合理预期会导致问题:

char c; 
int numBooks; 
while((c = fgetc(books)) != EOF) { 
    if(c == '\n') { 
         numBooks++; 
    } 
}
首先,
numBooks
是未初始化的,以后使用它可能会调用未定义的行为

其次,尽管在大多数系统上引起问题的可能性要小得多,
fgetc
返回
int
,它通常具有更宽的域(可以表示比
无符号字符更多的值)。这样做是有原因的。
fgetc
返回的任何实际字符值将作为
无符号字符
(即仅为正数)值。故障将导致
EOF
仅为负值)。这意味着
fgetc
通常可以返回257个值中的一个,通过直接转换为
char
您将丢弃其中一个值:错误处理值。换句话说,您无法再判断
fgetc
是否成功。当您达到
EOF
时会发生什么情况?将其转换为
字符
,将其视为字符值(如果不是),然后重试。。?回答错了

总之,
fgetc
返回
int
,因此将返回值存储在
int


numBooks
达到
INT_MAX
numBooks++时,会出现另一个问题将导致溢出。从技术上讲,这是未定义的行为,理论上可能导致分段错误。。。但我从未亲眼见过。尽管如此,您可能应该使用
无符号
类型,因为文件中的条目数为负数是没有意义的,不是吗

仔细想想,如果
structbookdatabookslist[numBooks]中的
numBooks
为负数(或足够大),当您访问更高的元素时,您可能会开始看到分段冲突

总之:当您只希望看到正数时,请使用无符号类型;对于大型数组,请使用动态分配(例如
malloc



请注意,这并没有涵盖所有的可能性,因为您没有提供详细的说明,因此不可能/不实际地这样做;您的segfault很可能是由您未提供的其他代码引起的。如果你更新了这个问题,请告诉我,这样我就可以更新这个答案,让世界继续旋转:)

什么是
numBooks
?如何检索它的值?为什么不使用调试器并找出哪行代码产生了错误?如果booklist在堆栈上并且numbooks很大,那么您可能会在某个地方耗尽堆栈空间。或者,在返回后,堆栈上的数据将消失,但您返回了指向它的指针。我将打印出
numbooks
的值。我也会在你们读的时候把每一行都打印出来,看看你们在撞车前能走多远。你们都很好!这是麻木书的问题。正如保罗·奥格尔维先生所说,书单最终太大了,因为麻木书是不正确的。非常感谢大家!非常感谢您的详细解释!这真的帮助我了解了发生了什么。我打印了numBooks,发现它返回了一个非常荒谬的数字。(当时是4195735。)我现在将努力修复代码的这一部分。确实是个奇怪的数字<代码>整数最大值
或者
整数最大值
<代码>整数最小值
可能被转换成一个
无符号整数
?嗯……您忘记了主要问题:
numBooks
未初始化且具有自动存储,这就是segfault背后的原因。@LPs:您可能应该将其作为一个答案发布。这一条解决了许多不太可能导致cae问题的次要质量问题,并省略了这一关键错误,而这一错误肯定是导致cae问题的原因。@LPs感谢您提供的额外细节。我错过了!哦!
char c; 
int numBooks; 
while((c = fgetc(books)) != EOF) { 
    if(c == '\n') { 
         numBooks++; 
    } 
}