【问题标题】:Segmentation fault error while trying to get file extension in C尝试在 C 中获取文件扩展名时出现分段错误错误
【发布时间】:2017-04-15 19:21:25
【问题描述】:

我正在尝试用 C 编写一个函数,输入一个文件,如果文件扩展名为 png、jpg 等,则返回 1。

这是我写的:

int estImage(struct dirent *fichier)
{
    char nomFichier[256];
    strncpy (nomFichier, fichier->d_name, 255);

    char *dot = strrchr(nomFichier, '.');

    char * listeExtensionImage[] = {".png", ".jpg", ".jpeg", ".bmp" };
    int len = sizeof(listeExtensionImage)/sizeof(listeExtensionImage[0]);

    printf(dot); //Just to test

    for (int i=0; i<len; i++)
    {
        if(!strcmp(listeExtensionImage[i], dot))
            return 1;
        else
            return 0;
    }
}

如果我输入一个不是图片的文件(例如.c文件),那么它会毫无问题地返回0,并且printf(dot)将显示“.c”。

但是,如果我尝试输入图片文件(.jpg 或我列出的任何其他文件),我会收到消息分段错误(核心转储)。 然后,我意识到问题出在这行:

if(!strcmp(listeExtensionImage[i], dot))

如果我删除了 for 指令,以及介于两者之间的所有内容,那么我就不再有错误了。

但我不明白为什么我会遇到这个问题,因为我在同一个程序中进行了类似的测试,并且它有效:

int estExecutable(struct dirent *fichier) 
{
   char nomFichier[256]; // Variable qui contiendra le nom du fichier
   strncpy (nomFichier, fichier->d_name, 255); 
   const char *dot = strrchr(nomFichier, '.'); 
   if(strcmp(dot,".exe")==0)
   {
       printf(nomFichier);
       return 1;
   }
   else
       return 0;
}       

这个函数确实有效,我看不出我的两个函数有什么区别。有人能帮助我吗?谢谢!

编辑:也试过这个版本,但得到了同样的错误:

int estImage(struct dirent *fichier)
{

    char nomFichier[256]; // Variable qui contiendra le nom du fichier
    strncpy (nomFichier, fichier->d_name, 255);
    char *dot = strrchr(nomFichier, '.');

    int retour=0;

    if( (!strcmp(dot,".jpg")) || (!strcmp(dot,".png")) || (!strcmp(dot,".jpeg")) || (!strcmp(dot,".bmp")) ) 
        retour = 1;

    return retour;
}

【问题讨论】:

标签: c fedora


【解决方案1】:

你想要这个:

int estImage(struct dirent *fichier)
{
    char nomFichier[256];
    strncpy (nomFichier, fichier->d_name, 255);

    char *dot = strrchr(nomFichier, '.');

    if (dot == NULL)
       return 0;  // no extension => it's not an image

    char * listeExtensionImage[] = {".png", ".jpg", ".jpeg", ".bmp" };
    int len = sizeof(listeExtensionImage)/sizeof(listeExtensionImage[0]);

    printf(dot); //Just to test

    for (int i=0; i<len; i++)
    {
        if (strcmp(listeExtensionImage[i], dot) == 0)
            return 1;   // image extension found
    }

    return 0;   // no image extension found
}

【讨论】:

  • 手动比较很难。它可能已经在 30 cmets 中讨论过,但如果有一个公认的答案,它应该独立存在。您为什么不给出解释并突出差异?
【解决方案2】:

所以,感谢玛丽安,我们发现了错误。函数 estImage() 在 for 循环中调用,它应该列出目录中的所有文件。该循环可能捕获了一个不可见的文件,或者名称为空的文件,并且 dot 变量为 NULL。所以,工作代码是:

int estImage(struct dirent *fichier)
{

    char nomFichier[256]; // Variable qui contiendra le nom du fichier
    strncpy (nomFichier, fichier->d_name, 255);

    char *dot = strrchr(nomFichier, '.');

    int retour=0;


    if( dot!=NULL && ((!strcmp(dot,".jpg")) || (!strcmp(dot,".png")) || (!strcmp(dot,".jpeg")) || (!strcmp(dot,".bmp"))) ) //Si le fichier est une image
        retour = 1; // On retourne 1

    return retour;


}

非常感谢所有帮助过我的人!

【讨论】:

  • 但是这个功能很丑。 char * listeExtensionImage[] = {".png", ".jpg", ".jpeg", ".bmp" }; 的原始版本要优雅得多。不,没有什么神秘之处。如果你有一个没有扩展名的文件(这很常见)strchr(xxx, '.'); 返回NULL
猜你喜欢
  • 1970-01-01
  • 2018-06-27
  • 2017-10-05
  • 2022-10-04
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 2013-10-20
  • 2013-09-12
相关资源
最近更新 更多