C - 为什么我的函数返回NULL?

时间:2015-10-30 10:53:17

标签: c function memory-management cs50

我认为我的函数正在返回NULL,因为我将它初始化为它。但如果我不这样做,我会收到编译错误。

这只是我在test.c文件中进行测试的原型。因此,当我开始工作时,我会将lookup函数复制回正确的文件中。

这是pset6的{​​{1}}的一部分,如果这有助于任何人。

cs50

我正在使用所有正确的库,当我尝试包含它时,它搞砸了我的代码预览!

7 个答案:

答案 0 :(得分:4)

 char temp[strlen(extension)];

您不会为尾随空字符保留空间,也不会设置它!例如,char temp[strlen(extension) + 1] = {0};

然后:

char* filetype = NULL;

if (strcmp(temp,  "html") == 0)
    strcpy(filetype, "text/html"); 
必须分配

filetype指向对象,例如使用malloc,否则strcpy正在使用空指针进行复制。

答案 1 :(得分:3)

您确定extension仅包含没有.的扩展名吗?我更喜欢使用_stricmpstrcmpi来比较不区分大小写。为什么要strcpyfiletype而不是分配?你只有没有malloc的指针:

const char* lookup(const char* extension)
{
const char* filetype = NULL;

if (_stricmp(extension, "html") == 0)
    filetype = "text/html"; 
else if(_stricmp(extension, "css") == 0)
    filetype = "text/css";

else if(_stricmp(extension, "js") == 0)
    filetype = "text/js";

else if(_stricmp(extension, "jpg") == 0)
    filetype = "image/jpg";

else if(_stricmp(extension, "ico" ) == 0)
    filetype = "image/x-icon";

else if(_stricmp(extension, "gif") == 0)
    filetype = "image/gif";

else if(_stricmp(extension, "png") == 0)
    filetype = "image/png";

return filetype;
}

或更好:

const char* lookup(const char* extension)
{
  char * ext[] = { "html", "text/html", "css", "text/css", "js", "text/js", "jpg", "image/jpg", NULL };


  for ( int i = 0; ext[i]; i += 2 )
  {
    if ( !stricmp( extension, ext[i] ) )
      return ext[i+1];
  }
  return NULL;
}

答案 2 :(得分:1)

小心这个:

char temp[strlen(extension)];

在C中,字符串以NULL结尾,因此您实际上不会为终止字符保留空间,因此您的临时字符串在运行时实际上可能看起来更长。

请改为:

char temp[strlen(extension)+1];

后来:

temp[i] = '\0';

答案 3 :(得分:1)

您必须为终止空值分配空间并终止字符串:

char temp[strlen(extension)+1];

for (int i = 0; i < strlen(temp); i++)
{
    if (isalpha(extension[i]))
        temp[i] = tolower(extension[i]);
}
temp[i]= '\0';

另请注意,如果扩展名包含数字或任何其他非字母字符,则不会复制。

答案 4 :(得分:1)

你缺少临时'0'额外的空间;你需要写一些像

这样的东西
char temp[strlen(extension) + 1];

并分配一些空间来存储文件类型;可能是写作

char filetype[50]; // 50 should be enought for your case 

尽管如此,我建议使用strcasecmp()(函数比较两个字符串,忽略字符的大小写)而不是strcmp()并删除看似无用的文件类型。 这就是它的样子:

#include <stdio.h>
#include <strings.h>

const char *lookup(const char *extension);

int main(void)
{
    const char *const type = "css";
    const char *ending = lookup(type);
    printf("the exstension: %s\nis of type = %s\n", type, ending);
}

const char *lookup(const char *extension)
{
    if (strcasecmp(extension, "html") == 0)
        return "text/html";

    else if (strcasecmp(extension, "css") == 0)
        return "text/css";

    else if (strcasecmp(extension, "js") == 0)
        return "text/js";

    else if (strcasecmp(extension, "jpg") == 0)
        return "image/jpg";

    else if (strcasecmp(extension, "ico" ) == 0)
        return "image/x-icon";

    else if (strcasecmp(extension, "gif") == 0)
        return "image/gif";

    else if (strcasecmp(extension, "png") == 0)
        return "image/png";

    return NULL;
}

更具伸缩性的解决方案可以使用数组来描述扩展,因此如果添加新类型,则无需更改代码:

#include <stdio.h>
#include <strings.h>

struct Type {
    const char *const extension;
    const char *const mime;
} knownTypes[] = {
    { "html", "text/html"    },
    { "css",  "text/css"     },
    { "js",   "text/js"      },
    { "jpg",  "image/jpg"    },
    { "ico",  "image/x-icon" },
    { "gif",  "image/gif"    },
    { "png",  "image/png"    }
};

static const size_t nbKnownTypes = sizeof(knownTypes) / sizeof(struct Type);

const char* lookup(const char* extension);

int main(void)
{
    const char *const type = "Css";
    const char *ending = lookup(type);
    printf("the exstension: %s\nis of type = %s\n", type, ending);
}

const char *lookup(const char *extension)
{
    for (size_t i = 0; i < nbKnownTypes; i++) {
         struct Type type = knownTypes[i];
         if (strcasecmp(extension, type.extension) == 0)
             return type.mime;
    }

    return "Unknown mime type";
}

对于这种设置,您可以轻松地添加新类型的扩展名和mime类型(您可以将此结构放在单独的c文件中,这可能会阻止重新编译所有内容,但这是另一个故事)

答案 5 :(得分:0)

1。您的代码显示未定义的行为。在您的函数lookup -

char temp[strlen(extension)];     // basically char temp[3]

并使用循环填充完整数组,而不为'\0'留出空间,然后使用%s打印并将其传递给strcmp也会导致 UB

像这样声明数组temp -

char temp[strlen(extension)+1)]={'\0'};        // +1 for null character

2。当您复制指针filetype -

if (strcmp(temp,  "html") == 0)
    strcpy(filetype, "text/html"); 

但它指向NULL,因为它没有分配任何内存。

使用malloc将内存分配给filetype

答案 6 :(得分:-1)

char* filetype = NULL没有内存空间来使用strcpy函数复制字符串。将此代码替换为char* filetype = malloc(20)