在C中调用fgets时出现分段错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C中调用fgets时出现分段错误相关的知识,希望对你有一定的参考价值。

我正在我的C代码中编写一个函数,并且我的函数被要求随机搜索由给定数量的字符组成的文件中的单词。这是我的代码:

#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#include "string.h"
void ExtMot(char nom, char *s[80], int n )
{
    FILE *fp ; 
    int i=0, j=0,x ;
    int taille= n  ;
    srand (time (NULL)) ;
    fp = fopen (nom,"r") ;
    while (fgets (s, 80, fp))
    {
        i++ ;
    }

    printf (" enter the size ") ;
    scanf ("%d",&taille) ;
    do
    {
        x= rand ()* rand() % i ; 
        rewind(fp);  
        while (fgets (s, 80, fp))
        {
           j++ ;
           if (j==x) break ;
        }
        s[strlen (s)]='' ;
        if (strlen (s)-1 == taille )
            break ;
        else
            j=0 ;
    } while (1) ;
    fclose (fp) ;
}


void main ()
{
   char mot[80];
   ExtMot("C:\Users\asus\Desktop\c_projet\hello\projet.txt",*mot,6);
   printf ("%s",mot);
}

我调试了我的代码,并在调用fgets函数和控制台应用程序崩溃时出现了分段错误错误。有人可以帮我识别错误吗?

答案

我想知道你的代码是如何编译的(如果有的话)。您应该为这些类型错误左右收到警告。以下调整应该使您的代码编译(我使用-Wall编译),但我无法证明它的可靠性,因为我不知道您的helloprojet.txt文件。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>
// these headers were wrapped in quotes "", instead of angle brackets <>

void ExtMot(char *nom, char *s, int n) {
    FILE *fp;
    int j = 0, i, x;
    int taille = n;
    srand(time(NULL));
    if (!(fp = fopen(nom, "r"))) {
        fprintf(stderr, "Could not open file: %s
", strerror(errno));
        return;
    }
    // always check if the result of fopen == null

    for (i = 0; fgets(s, 80, fp); i++)
        ;

    // rest of the code here...
}

int main(void) {
    char mot[80];
    ExtMot("C:\Users\asus\Desktop\c_projet\hello\projet.txt", mot, 6);
    printf("%s
", mot);
    return 0;
}

您尝试使用双引号包含C标准库标题,而不是像您应该的那样包含尖括号。如果头文件与源文件位于同一目录中,则只对包含使用双引号。你似乎对ExtMot()的参数中的类型有正确的想法,但它不会像你期望的那样工作。 char nom是一个单一角色。 char *m[80]是一个由80个指针组成的数组,而不是80个字符的数组。

*mot是指向80个字符数组的指针。 mot是80个字符的阵列。因此,不是将char缓冲区发送到ExtMot(),而是在内存中发送char缓冲区的位置,这将破坏您的代码(并且应该触发编译器的警告)。请参阅上面的代码,了解如何将字符串传递给函数。

编辑:此外,void main()已经过时,可怕的做法。如果您不期望任何命令行参数,请始终使用int main(void)并返回0。

另一答案

使用*mot,您传递的是一个预期指针的字符值(实际上您的编译器应该警告您)。因此,你传递一个不指向有效内存的“内存地址”,然后fgets写入这样的内存。此外,您将文件名作为单个字符传递,其中它应该是一个字符串。并始终检查fopen的返回值。

按如下方式更改您的程序,至少此问题应该消失:

#include <errno.h>

void ExtMot(char *nom, char *s, int n ) {
   ...
   fp = fopen (nom,"r");
   if (!fp) {
      fprintf(stderr, "error opening %s: %s", nom, strerror(errno));
      return;
   }
   ...
}

int main ()
{
   char mot[80];
   ExtMot("C:\Users\asus\Desktop\c_projet\hello\projet.txt",mot,6);
   printf ("%s",mot);
}

以上是关于在C中调用fgets时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

为啥在访问二级指针时出现分段错误错误? C语言

在调用函数中取消引用指针时出现分段错误

从 C 调用汇编函数时出现分段错误错误

设置堆栈后在 C 中调用 printf 时出现分段错误

调用 c 函数时出现分段错误

调用printf%s时出现分段错误