在C中删除文件表示该文件不是';找不到
我正在处理一个c项目,需要从目录中删除一个文件。出于某种原因,尽管它一直说它无法删除,因为文件或目录不存在。下面是我用来删除文件的代码在C中删除文件表示该文件不是';找不到,c,delete-file,C,Delete File,我正在处理一个c项目,需要从目录中删除一个文件。出于某种原因,尽管它一直说它无法删除,因为文件或目录不存在。下面是我用来删除文件的代码 void deleteOldestLog() { FILE *fp; char path[FILE_PATH_BUF_LEN], *fileName; fp = popen("ls -tr /home/myfolder/logs/ |head -1", "r"); if (fp == NULL) { pr
void deleteOldestLog()
{
FILE *fp;
char path[FILE_PATH_BUF_LEN], *fileName;
fp = popen("ls -tr /home/myfolder/logs/ |head -1", "r");
if (fp == NULL)
{
printf("Failed to run command");
}
else
{
char removalPath[FILE_PATH_BUF_LEN];
while ((fileName = fgets(path, sizeof(path)-1, fp)) != NULL)
{
sprintf(removalPath, "/home/myfolder/logs/%s", fileName, sizeof(fileName)-1);
printf("Removing file: %s", removalPath);
if (remove(removalPath) != 0)
{
perror("ERROR DELETING LOG");
}
else
{
printf("Successfully deleted %s", removalPath);
}
break;
}
pclose(fp);
}
}
尽管它说它找不到文件,因为它不存在,但我知道这不是真的,因为如果我运行ll
,后跟c程序打印的路径,它会返回我试图删除的文件
我认为这可能是因为fgets将“\0”放在字符串的末尾,这将阻止删除工作
如何修复此问题?由
fgets()读取的文件名末尾有一个新行。您的文件名实际上不会以换行符结尾
尝试删除换行符时,请执行以下操作:
sprintf(removalPath, "/home/myfolder/%s", fileName, sizeof(fileName)-1);
但是,为了有效,需要使用strlen()
而不是sizeof()
,并且需要修改格式字符串:
sprintf(removalPath, "/home/myfolder/%.*s", (int)strlen(fileName)-1, fileName);
*
的参数必须是int
,strlen()
返回一个size\u t
;因此,演员阵容。(如果您打开警告,GCC将对此发出警告;至少使用-Wall
)
给你的提示:当有疑问时,打印字符串。我通常会使用这样的格式。注意字符串周围的尖括号:
printf("Removing: <<%s>>\n", removalPath);
格式字符串需要1个参数,一个字符串。该调用提供两个值,一个字符串和一个长度。所以,第一个问题是,有一个剩余的论点。这通常不会造成损害,但要注意。大概,传递长度减1的原因是丢失最后一个字符。printf()
系列中的格式可以用一个或两个数字修饰,其中一个或两个可以用*
代替整数值。这些数字约束格式化值的长度。当你写作时:
%.*s
您声明输出的长度应该正好是字符串本身之前作为参数传递的int
值指定的长度。因此,修订如下:
sprintf(removalPath, "/home/myfolder/%.*s", (int)strlen(fileName)-1, fileName);
(我在添加此信息时刚刚修复了此问题。)
我还没有将错误检查添加到sprintf()
等的输出中,这并不罕见;但是,最佳编码实践确实确保像sprintf()
这样的函数返回您期望的值(即写入字符串的字符数,不包括尾随的null'\0'
)
(旁白:一般来说,使用snprintf()
比使用sprintf()
更好;这样可以避免缓冲区溢出
snprintf(removalPath, sizeof(removalPath), "/home/myfolder/%.*s",
(int)strlen(fileName)-1, fileName);
但是,MSVC下的*snprintf()
函数的行为不同于C标准(C99,C11)规定的行为。更糟糕的是,在vsnprintf_s()
和其他_s
函数的情况下,MSVC和C标准之间的参数列表不同。)通过fgets()
读取的文件名末尾有一个换行符。您的文件名实际上并不以换行符结尾
尝试删除换行符时,请执行以下操作:
sprintf(removalPath, "/home/myfolder/%s", fileName, sizeof(fileName)-1);
但是,为了有效,需要使用strlen()
而不是sizeof()
,并且需要修改格式字符串:
sprintf(removalPath, "/home/myfolder/%.*s", (int)strlen(fileName)-1, fileName);
*
的参数必须是一个int
,strlen()
返回一个size\u t
;因此该类型的演员必须是演员。(如果您打开警告,GCC将警告这类事情;至少使用-Wall
)
提示:如果有疑问,请打印字符串。我通常会使用这样的格式。请注意字符串周围的尖括号:
printf("Removing: <<%s>>\n", removalPath);
格式字符串需要一个参数,一个字符串。调用提供两个值,一个字符串和一个长度。因此,第一个问题是有一个剩余参数。这通常不会造成损害,但要注意。传递长度减一的原因可能是丢失了最后一个字符。printf()中的格式
族可以用一个或两个数字装饰,其中一个或两个可以用*
代替整数值。这些数字约束格式化值的长度。写入时:
%.*s
您声明输出的长度应正好是字符串本身之前作为参数传递的int
值指定的长度。因此修订:
sprintf(removalPath, "/home/myfolder/%.*s", (int)strlen(fileName)-1, fileName);
(我在添加此信息时刚刚修复了此问题。)
我还没有在sprintf()
等的输出中添加错误检查。这并不少见;但是,最佳编码实践确实确保像sprintf()
这样的函数返回您期望的值(即写入字符串的字符数,不包括尾随的null'\0'
)
(旁白:一般来说,使用snprintf()
比使用sprintf()
更好;这样可以避免缓冲区溢出
snprintf(removalPath, sizeof(removalPath), "/home/myfolder/%.*s",
(int)strlen(fileName)-1, fileName);
但是,MSVC下的*snprintf()
函数的行为不同于C标准(C99,C11)规定的行为。更糟糕的是,在vsnprintf_s()
和其他_s
函数的情况下,MSVC和C标准之间的参数列表不同。)我确实在问题中提到了这一点,我认为这是问题的原因,但不知道如何解决该问题]为什么需要修改格式字符串?我了解所有其他内容,但不了解格式字符串。非常感谢您的帮助。感谢您的详细解释。非常感谢。我确实在问题中提到了这一点我认为这是导致问题的原因,但不知道我如何解决该问题]为什么需要修改格式字符串?我了解所有其他内容,但不了解格式字符串。非常感谢您的帮助。感谢您的详细解释。非常感谢。这是一个复制/粘贴错误,现已修复,因此日志中都有,但sti中没有你的printf()会有问题<