주어진 전체 경로를 디렉토리, 파일명 및 확장자로 분리하는 다음 함수를 작성했습니다.memmove는 가비지를 떠납니다 - C
#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
을 사용했고 이상한 부분은 첫 번째 것이 잘 작동한다는 것입니다.
도움을 주시면 감사하겠습니다.
한쪽 포인트 :'/' Windows에서 유효한 디렉토리 구분 기호이기도합니다. 사용자가 임의의 경로 이름을 제공 할 수 있고''/ ''를 사용하여 코드를 제공하면 코드가 손상됩니다. ''C : foo.txt ''와 같은 파일 이름의 경우를 다루는 것이 필요할 수도 있습니다. 아마도 DOS 레거시에서 여전히 유효한 것입니다 ("C 드라이브의 현재 디렉토리 : foo.txt"라는 파일을 참조하십시오).). –