作爲學習C的一部分,我編寫了以下代碼以將目錄名稱與文件名稱組合在一起。例如:combine("/home/user", "filename")
將導致/home/user/filename
。這個功能預計可以跨平臺使用(至少在所有流行的Linux發行版以及Windows 32和64位上)。組合目錄和文件路徑 - C
這是代碼。
const char* combine(const char* path1, const char* path2)
{
if(path1 == NULL && path2 == NULL) {
return NULL;
}
if(path2 == NULL || strlen(path2) == 0) return path1;
if(path1 == NULL || strlen(path1) == 0) return path2;
char* directory_separator = "";
#ifdef WIN32
directory_separator = "\\";
#else
directory_separator = "/";
#endif
char p1[strlen(path1)]; // (1)
strcpy(p1, path1); // (2)
char *last_char = &p1[strlen(path1) - 1]; // (3)
char *combined = malloc(strlen(path1) + 1 + strlen(path2));
int append_directory_separator = 0;
if(strcmp(last_char, directory_separator) != 0) {
append_directory_separator = 1;
}
strcpy(combined, path1);
if(append_directory_separator)
strcat(combined, directory_separator);
strcat(combined, path2);
return combined;
}
我對以上代碼有以下問題。
- 考慮編號爲1,2,3的行。所有這3行都用於獲取字符串中的最後一個元素。看起來我正在爲這麼小的事情寫更多的代碼。從
char*
字符串獲取最後一個元素的正確方法是什麼? - 要返回結果,我使用
malloc
分配新字符串。我不確定這是做到這一點的正確方法。來電者是否期望釋放結果?我怎麼能指出來電者他必須釋放結果?有沒有更容易出錯的方法? - 你如何評價代碼(差,平均,好)?哪些領域可以被強化?
任何幫助將是偉大的。
編輯
固定討論的所有問題和實施的更改建議。這是更新的代碼。
void combine(char* destination, const char* path1, const char* path2)
{
if(path1 == NULL && path2 == NULL) {
strcpy(destination, "");;
}
else if(path2 == NULL || strlen(path2) == 0) {
strcpy(destination, path1);
}
else if(path1 == NULL || strlen(path1) == 0) {
strcpy(destination, path2);
}
else {
char directory_separator[] = "/";
#ifdef WIN32
directory_separator[0] = '\\';
#endif
const char *last_char = path1;
while(*last_char != '\0')
last_char++;
int append_directory_separator = 0;
if(strcmp(last_char, directory_separator) != 0) {
append_directory_separator = 1;
}
strcpy(destination, path1);
if(append_directory_separator)
strcat(destination, directory_separator);
strcat(destination, path2);
}
}
在新版本中,調用者來分配足夠的緩衝區,發送給combine
方法。這避免了使用malloc
和free
問題。這是用法
int main(int argc, char **argv)
{
const char *d = "/usr/bin";
const char* f = "filename.txt";
char result[strlen(d) + strlen(f) + 2];
combine(result, d, f);
printf("%s\n", result);
return 0;
}
有關更多改進的建議嗎?
好點。我意識到泄漏。但是,對我而言,這是一場新的災難。你能解釋一下如何解決問題嗎? – 2010-06-29 16:37:04
@Appu:'free(two)'和'free(「bar」)'是一樣的。這可能不是_disaster_。但它是不確定的。 – 2010-06-29 16:44:27
既然你快捷,如果其他參數是空的,返回'path1'或'path2',用戶不知道它們是否應該釋放返回的值。接得好。 – jdmichal 2010-06-29 18:17:00