我得到核心转储,我不知道如何解决。我搜索了其他问题并搜索了我的问题,但我无法弄清楚如何解决这个问题...
以下是代码:
const char checkExtension(const char *filename)
{
const char *point = filename;
const char *newName = malloc(sizeof(filename-5));
if((point = strrchr(filename,'.palz')) != NULL )
{
if(strstr(point,".palz") == 0)
{
strncpy(newName, filename, strlen(filename)-5);
printf("%s\n",newName ); // the name shows correctly
return newName; // Segmentation fault (core dumped)
}
}
return point;
}
该函数名为char checkExtensions(const char *filename)
。由于我在网上找到的解决方案,我添加了const,但到目前为止我还没有能够使它工作...
提前感谢您的帮助!
答案 0 :(得分:3)
您的代码存在许多问题。以下是其中一些:
char
这是一个单个字符。您需要返回一个指向字符数组的指针,即C字符串。sizeof()
,这会产生指针的大小。'.palz'
(一个字符文字)传递给strrchr
,该char
需要一个'.'
。您的意思是#include <string.h>
#include <stdio.h>
void GetNewFileName(const char *fileName, char *newFileName)
{
const char *dot = strrchr(fileName, '.');
if (dot)
{
if (strcmp(dot, ".palz") == 0)
{
size_t len = dot - fileName;
memcpy(newFileName, fileName, len);
newFileName[len] = 0;
return;
}
}
size_t len = strlen(fileName);
memcpy(newFileName, fileName, len);
newFileName[len] = 0;
return;
}
int main(void)
{
char fileName[256];
char newFileName[256];
strcpy(fileName, "foo.bar");
GetNewFileName(fileName, newFileName);
printf("%s %s\n", fileName, newFileName);
strcpy(fileName, "foo.bar.palz");
GetNewFileName(fileName, newFileName);
printf("%s %s\n", fileName, newFileName);
strcpy(fileName, "foo.bar.palz.txt");
GetNewFileName(fileName, newFileName);
printf("%s %s\n", fileName, newFileName);
return 0;
}
。更好的方法是让调用者分配内存。这是一个完整的程序,展示了如何:
strcmp
<强>输出强>
foo.bar foo.bar foo.bar.palz foo.bar foo.bar.palz.txt foo.bar.palz.txt
请注意{{1}}将敏感与字母大小写进行比较。在Windows上,文件名对大小写不敏感。我将把这个问题留给你处理。
通过让调用者分配内存,允许他们选择分配内存的位置。如果愿意,他们可以使用本地堆栈分配缓冲区。调用者分配内存很容易,因为新文件名永远不会超过原始文件名。
答案 1 :(得分:1)
这很可能是你的问题:
const char *newName = malloc(sizeof(filename-5));
首先,filename的类型为const char *
,这意味着(filename - 5)
也属于此类型。因此,sizeof(filename - 5)
将始终返回架构的指针数据类型的大小(x32为4,x64为8)。
因此,根据您的体系结构,您要拨打malloc(4)
或malloc(8)
。
其余的代码甚至无法编译,并且它有严重的字符串操作问题,所以很难说出你的目标是什么。我想strncpy()
正在将过多的数据复制到newName
缓冲区中,导致缓冲区溢出。
如果您的目标是从路径中提取文件名,那么您应该只使用char *basename(char *path)
。
答案 2 :(得分:0)
您的代码存在几个相当严重的问题。在我输入时进行补充,因此它可能无法立即第一次修复所有内容。忍受我。
您需要返回char *
,而不是char
。
const char checkExtension(const char *filename)
{
const char *point = filename;
你malloc
内存,但指令流并不能保证它会被释放或返回。
sizeof(filename)
应为strlen(filename)
,减去5( sans 扩展名),但+1(终止为0)。
const char *newName = malloc(sizeof(filename-5));
strrchr
搜索单个字符。有些编译器允许“多字节字符常量”,但是他们期望像2那样 - 而不是 5 。由于您知道字符串的长度和开头,因此请使用strcmp
。 (首先确保 至少5个字符。如果没有,则无论如何都不用于测试。)
if((point = strrchr(filename,'.palz')) != NULL ) {
呃,strstr
在字符串中搜索字符串,如果找不到则返回0(实际上是NULL
)。这与您之前的测试相矛盾。删除它。
if(strstr(point,".palz") == 0)
{
strncpy
复制n
个字符,但如果没有复制,那么着名的(和记录的)不会添加终止0。你自己必须这样做。
..这实际上是malloc
行应该出现的地方,就在使用和返回之前。
strncpy(newName, filename, strlen(filename)-5);
printf("%s\n",newName ); // the name shows correctly
return newName; // Segmentation fault (core dumped)
}
}
您在此处返回原始字符串。你怎么知道你需要free
呢?如果您覆盖之前的 char *
,其内存将会丢失。最好返回原始字符串的副本(因此可以随时释放它),或者,如我所愿,返回NULL
以指示调用例程“不需要进一步操作”。
return point;
}
希望我没有忘记任何事情。
答案 3 :(得分:0)
您的代码存在一些问题:
错误的退货类型:
const char checkExtension(const char *filename){
您需要返回指针(const char *
),而不是单个字符。
内存不足:
const char checkExtension(const char *filename){ const char *newName = malloc(sizeof(filename-5));
您正在分配指针大小(char *
),通常为4或8.您需要致电strlen()
以找出大小字符串:
多字节字符:
if((point = strrchr(filename,'.palz')) != NULL ) {
'.palz'
是一个多字节字符文字。虽然在C中允许这样做,但它的值是实现定义的,可能无法达到您的预期。字符串文字使用 double 引号(".palz"
)。
没有终止零:
strncpy(newName, filename, strlen(filename)-5);
请注意,strncpy()
不一定是空终止目标字符串。它最多写 strlen(filename)-5
个字符。如果源字符串包含更多字符(如您的情况),则不将写入终止零。
我不确定你到底要做什么。也许是这样的:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *checkExtension(const char *filename)
{
int len = strlen (filename)-5;
char *newName = NULL; /* return NULL on allocation failure. */
if (len > 0 && !strcmp (filename+len, ".palz")) {
newName = malloc (len+1);
if (newName) {
memcpy (newName, filename, len);
newName[len] = 0;
}
}
return newName;
}
int main (int ac, char **av)
{
if (ac > 1) {
const char *p = checkExtension (av[1]);
puts (p ? p : "NULL");
} else {
puts ("?");
}
return 0;
}
答案 4 :(得分:0)
这里有多个错误。你还没有说过你想要实现的目标,这必须从代码中暗示。您已将point
和newName
声明为const
,但已使用值重新分配。您已对strstr() == 0
进行了strstr() == NULL
测试。您已调用strrchr(filename,'.palz')
但发送了一个字符串而不是char。然后,在有机会使用之前,您已经返回了超出范围的局部变量point
,因为它未被声明为静态。因此,无论是返回char还是char指针都无关紧要。
char *checkExtension(const char *filename) {
// if filename has extension .palz return a pointer to
// the filename stripped of extension or return NULL
char *point;
static char newName[512];
strncpy(newName, filename, 512);
if ((point = strstr(newName, ".palz")) != NULL ) {
if (strlen (point) == 5) {
*point = 0; // string terminator
// printf("%s\n",newName ); // use only for debugging
return newName;
}
}
return NULL;
}
或者提供一个函数可以修改的字符串 -
char *checkExtension(const char *filename, char *newName) { ... }
或者提供函数可以修改的文件名 -
char *checkExtension(char *filename) {
char *point;
if ((point = strstr(filename, ".palz")) != NULL ) {
if (strlen (point) == 5) {
*point = 0; // string terminator
return filename;
}
}
return NULL;
}