C-验证文件的访问权限';s目录
我想检查是否可以在目录中创建文件。此目录是存放我的C-验证文件的访问权限';s目录,c,C,我想检查是否可以在目录中创建文件。此目录是存放我的dst文件的目录。要知道是否可以在目录中创建文件,此目录应具有'w'访问权限 我搜索了如何获取文件的目录名,找到了dirname(char*)函数。但是这个函数会修改给定的字符串。我想保持我的dst字符串不变 这段代码正在运行,但并不十分干净,我想知道是否有其他方法来完成它 const char*dst=“目录/文件”; char*dstDir=(char*)malloc(sizeof(char)*(strlen(dst)+1); strcpy(
dst
文件的目录。要知道是否可以在目录中创建文件,此目录应具有'w'
访问权限
我搜索了如何获取文件的目录名,找到了dirname(char*)
函数。但是这个函数会修改给定的字符串。我想保持我的dst
字符串不变
这段代码正在运行,但并不十分干净,我想知道是否有其他方法来完成它
const char*dst=“目录/文件”;
char*dstDir=(char*)malloc(sizeof(char)*(strlen(dst)+1);
strcpy(dstDir,dst);
目录名(dstDir);
if(访问(dstDir,W_OK)=-1){
佩罗尔(dstDir);
免费(dstDir);
出口(1);
}
免费(dstDir);
注意:这里必须使用malloc吗?您可以使用静态字符数组
char dstDir[LARGE_ENOUGH_BUF_SIZE] = "\0";
dirname(strcat(dstDir, dst));
//...
由于
dirname
是一个POSIX函数,您还应该能够使用POSIX函数strdup
来分配字符串的副本
dirname
函数不一定返回传递给它的指针。它可以指向某些内部存储(静态或线程本地),并且可以通过后续调用dirname
来覆盖
考虑到上述情况,我建议如下:
const char* dst = "directory/file";
char* dstBuf = strdup(dst);
if (!dstBuf) {
fprintf(stderr, "Memory allocation error!\n");
exit(1);
}
char* dstDir = dirname(dstBuf);
if (access(dstDir, W_OK) == -1) {
perror(dstDir);
free(dstBuf);
exit(1);
}
free(dstBuf);
为字符串副本使用动态分配的缓冲区的另一种方法是使用可变长度数组(VLA)。该备选方案如下所示:
const char* dst = "directory/file";
char dstBuf[strlen(dst) + 1];
strcpy(dstBuf, dst);
char* dstDir = dirname(dstBuf);
if (access(dstDir, W_OK) == -1) {
perror(dstDir);
exit(1);
}
但是,VLA支持在C标准中是可选的,并且不是C++17标准的一部分。是的,我确实可以,但是什么是
足够大的大小?如果我的代码适用于所有可能的情况,不是更好吗?例如,2048字符的静态数组是否比适应性的malloc
更好?这是对您是否必须使用malloc的问题的回答。是的,缓冲区必须足够大,以适应各种可能的情况。好吧,一个足够大的缓冲区大小“可能”比分配和释放一块内存要好,这要看情况而定。调用malloc有其副作用,静态块只消耗堆栈上的特定大小。最好对缓冲区(当前为dstDir
)和dirname
的返回值使用单独的指针变量。当传递给dirname
的字符串不包含斜杠(导致dirname
返回“
)时,这也会起作用。但是请确保释放由malloc
返回的指针,而不是由dirname
返回的指针!我不明白,返回值与更改后的给定字符串不一样?man
表示,在不再需要函数返回的指针之前,不应修改或释放指针。但是我不使用它。dirname
可以修改dstDir
,但它不必这样做。它可以返回指向某个内部存储器的指针。我不知道返回的字符串是否可以修改。(特别是当手册页说它返回“
时,它没有说明返回字符串的内容是可修改的。)好的,谢谢,这比我所做的更复杂,但是如果没有其他方法way@Ephesiel另一种方法是使用可变长度数组(VLA)。我将把这个添加到答案中。我有这个警告:代码> ISO C++禁止可变长度数组'dSTBUF '/COD> @ AffSEILL Trtrue,可变长度数组不是C++标准的一部分。我在回答的末尾加了一条关于这一点的注释。