gpt4 book ai didi

c - memmove 留下垃圾 - C

转载 作者:行者123 更新时间:2023-12-02 23:34:00 26 4
gpt4 key购买 nike

我编写了以下函数,将给定的完整路径拆分为目录、文件名和扩展名。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct path_info {
char *directory;
char *filename;
char *extension;
};

#ifdef WIN32
const char directory_separator[] = "\\";
#else
const char directory_separator[] = "/";
#endif

struct path_info* splitpath(const char *full_path)
{
size_t length = strlen(full_path);
struct path_info *p = (struct path_info*) malloc(sizeof(struct path_info) + length + 3); /* Extra space for padding and shifting */
if(p)
{
char *path = (char *) &p[1]; /* copy of the path */
char *end = &path[length + 1];
char *extension;
char *last_separator;

/* copy the path */
strcpy(path, full_path);
*end = '\0';
p->directory = end;
p->extension = end;
p->filename = path;

last_separator = strrchr(path, directory_separator[0]); /* Finding the last directory separator */
if(last_separator) {
memmove(last_separator + 1, last_separator, strlen(last_separator)); /* inserting a directory separator where null terminator will be inserted */
p->directory = path;
*(++last_separator) = '\0'; /* Truncate the directory path */
p->filename = ++last_separator; /* Taking the remaining as file name */
}

/* Finding the extension starts from second character. This allows handling filenames
starts with '.' like '.emacs'.*/
extension = strrchr(&p->filename[1], '.');
if(extension) {

/* shifting the bytes to preserve the extension */
memmove(extension + 1, extension, strlen(extension)); /* problem happens here */
p->extension = extension + 1;

*extension = '\0'; /* Truncates the file name */
}
}
return p;
}


int main(void)
{
struct path_info *p = splitpath("C:\\my documents\\some.txt");
printf("Directory : %s\n", p->directory);
printf("Filename : %s\n", p->filename);
printf("Extension : %s\n", p->extension);
return 0;
}

这对于 GCC 上的给定输入非常有效。但它在 MSVC 上失败,在 extension 变量上留下一些垃圾数据。我对出错的地方添加了评论。我不明白为什么 memmove 在 MSVC 上的行为不同?我在两个地方使用了 memmove ,奇怪的是第一个工作正常。

如有任何帮助,我们将不胜感激。

最佳答案

尝试移动 strlen(extension) + 1 字节,这样不仅可以移动扩展字符,还可以移动尾随的空字符。例如,如果扩展名是“abc”,那么您只需将 3 个字符向前移动一个空格。 “c”字符后面可能有一个空字符,但之后没有空字符,因此当您移动字符时,字符串将变为未终止。

关于c - memmove 留下垃圾 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3200980/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com