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

C 为什么我的函数返回NULL?,c,function,memory-management,cs50,C,Function,Memory Management,Cs50,我认为我的函数返回了NULL,因为我初始化了它。但如果我不这样做,我会得到编译错误 这只是我在test.c文件中制作的一个原型,用于测试它。因此,当我让它工作时,我会将lookup函数复制回正确的文件中 这是cs50的pset6的一部分,如果这对任何人都有帮助的话 const char* lookup(const char* extension); int main(void) { const char* type = "css"; const char* ending = l

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

这只是我在
test.c
文件中制作的一个原型,用于测试它。因此,当我让它工作时,我会将
lookup
函数复制回正确的文件中

这是
cs50
pset6
的一部分,如果这对任何人都有帮助的话

const char* lookup(const char* extension);

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

const char* lookup(const char* extension)
{

    char temp[strlen(extension)];

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

    printf("temp = %s\n", temp);

    char* filetype = NULL;

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

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

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

    else if(strcmp(temp, "jpg") == 0)
        strcpy(filetype, "image/jpg");

    else if(strcmp(temp, "ico" ) == 0)
        strcpy(filetype, "image/x-icon");

    else if(strcmp(temp, "gif") == 0)
        strcpy(filetype, "image/gif");

    else if(strcmp(temp, "png") == 0)
        strcpy(filetype, "image/png");

    else
        return NULL;

    return filetype;
}
const char*查找(const char*扩展);
内部主(空)
{
const char*type=“css”;
常量字符*结束=查找(类型);
printf(“表达式:%s\n的类型=%s\n”,类型,结尾);
}
常量字符*查找(常量字符*扩展)
{
字符温度[strlen(扩展)];
对于(int i=0;i
我正在使用所有正确的库,当我试图包含它们时,它破坏了我的代码预览

 char temp[strlen(extension)];
您没有为尾随的空字符保留空间,并且从未设置它!例如,
chartemp[strlen(扩展)+1]={0}

然后:


filetype
必须分配指向的对象,例如使用
malloc
,否则
strcpy
将使用空指针进行复制。

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

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将内存分配给
文件类型。

注意:

char temp[strlen(extension)];
在C语言中,字符串以NULL结尾,因此您实际上没有为终止字符保留空间,因此您的临时字符串在运行时可能看起来更长

改为这样做:

char temp[strlen(extension)+1];
后来:

temp[i] = '\0';

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

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';
chartemp[strlen(扩展)+1];
对于(int i=0;i

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

您确定
扩展名
只包含扩展名而不包含
?我更喜欢使用
\u stricmp
strcmpi
来比较不区分大小写的代码。为什么要将strcpy改为
filetype
,而不是赋值?您只有不带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;
}

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

温度中缺少尾随“\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;
}
#包括
#包括
常量字符*查找(常量字符*扩展);
内部主(空)
{
const char*const type=“css”;
常量字符*结束=查找(类型);
printf(“表达式:%s\n的类型=%s\n”,类型,结尾);
}
常量字符*查找(常量字符*扩展)
{
if(strcasecmp(扩展名,“html”)==0)
返回“text/html”;
else if(strcasecmp(扩展名,“css”)==0)
返回“text/css”;
else if(strcasecmp(扩展名,“js”)==0)
返回“text/js”;
else if(strcasecmp(扩展名,“jpg”)==0)
返回“image/jpg”;
else if(strcasecmp(扩展名,“ico”)==0)
返回“图像/x图标”;
else if(strcasecmp(扩展名,“gif”)==0)
返回“image/gif”;
else if(strcasecmp(扩展名,“png”)==0)
返回“image/png”;
返回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;
}knownTypes[]={
{“html”,“text/html”},
{“css”,“text/css”},
{“js”,“text/js”},
{“jpg”,“image/jpg”},
{“ico”,“图像/x图标”},
{“gif”,“image/gif”},
{“png”,“image/png”}
};
静态常量大小\u t nbKnownTypes=sizeof(knownTypes)/sizeof(结构类型);
常量字符*查找(常量字符*扩展);
内部主(空)
{
const char*const type=“Css”;
常量字符*结束=查找(类型);
printf(“表达式:%s\n的类型=%s\n”,类型,结尾);
}
常量字符*查找(常量字符*扩展)
{
对于(大小i=0;i
使用这种设置,您可以只添加扩展名
#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";
}