我想为move(mv)Unix命令编写自己的代码。我是C语言的新手,显然对如何修复我的代码迷失了。如果两个输入都是文件名,我想执行诸如重命名文件的操作。如果dest_folder是目录,我想将文件移到该目录中。
但是我无法解决特定问题的代码,因为我对目录,尤其是C不太熟悉。该程序接受2个输入源和目标,然后执行必要的功能。我显然可以重命名文件,但是由于某种原因我无法将文件移至特定文件夹?
在将文件移动到特定目录方面需要帮助。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define SBUF 256
#define DBUF 256
int main(int ac, char *argv[])
{
DIR* dir_ptr; // the directory
struct dirent* direntp;
if( ac == 1 )
{
printf("Usage: %s MOVE\n", argv[0] );
exit(0);
}
if(ac>1 && ac<3)
{
printf("Error! few arguments provided " );
exit(0);
}
char src_folder[SBUF];
char dest_folder[DBUF];
strcpy(src_folder, argv[1]);
strcpy(dest_folder, argv[2]);
dir_ptr = opendir("."); //open directory
if ( dir_ptr == NULL )
{
perror( "." );
exit( 1 );
}
while( (direntp = readdir( dir_ptr )) != NULL )
{
if ( strcmp(direntp->d_name, dest_folder) !=0) //search file or directory
{
printf("found the file %s", dest_folder);
break;
}else
printf("not found");
break;
}
rename(src_folder, dest_folder);
closedir( dir_ptr );
return 0;
}
最佳答案
rename(3)
无法按照您希望的方式工作(我不知道为什么,请问委员会)。您不能按照手册页中的说明执行rename(some_file, some_directory)
。
只需使用stat(2)
(或必要时使用lstat(2)
)并检查您得到的信息即可。这是一个简短的,可运行的草图。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
// check if it is the same inode on the same device
#define SAME_INODE(a, b) ((a).st_ino == (b).st_ino && (a).st_dev == (b).st_dev)
// ALL CHECKS OMMITTED!
int main(int argc, char **argv)
{
struct stat statbuf_src, statbuf_dest;
char *src, *dest, *new_src, *new_dest;
char *current_directory;
if (argc != 3) {
fprintf(stderr, "usage: %s src dest\n", argv[0]);
exit(EXIT_FAILURE);
}
// work on copy
src = malloc(strlen(argv[1]) + 1);
dest = malloc(strlen(argv[2]) + 1);
strcpy(src, argv[1]);
strcpy(dest, argv[2]);
stat(src, &statbuf_src);
stat(dest, &statbuf_dest);
// there are many more, of course
printf("\"%s\" is a ", src);
if (S_ISREG(statbuf_src.st_mode)) {
puts("a regular file");
}
if (S_ISDIR(statbuf_src.st_mode)) {
puts("a directory");
}
printf("\"%s\" is a ", dest);
if (S_ISREG(statbuf_dest.st_mode)) {
puts("a regular file");
}
if (S_ISDIR(statbuf_dest.st_mode)) {
puts("a directory");
}
if (SAME_INODE(statbuf_dest, statbuf_src)) {
printf("%s and %s are the identical\n", src, dest);
}
// if that is not set you have to do it by hand:
// climb up the tree, concatenating names until the inodes are the same
current_directory = getenv("PWD");
printf("current directory is \"%s\"\n", current_directory);
// I'm pretty sure it can be done in a much more elegant way
new_src = malloc(strlen(src) + 1 + strlen(current_directory) + 1);
strcpy(new_src,current_directory);
strcat(new_src,"/");
strcat(new_src,src);
printf("new_src = %s\n",new_src);
new_dest = malloc(strlen(dest) + 1 + strlen(current_directory) + 1 + strlen(src) + 1);
strcpy(new_dest,current_directory);
strcat(new_dest,"/");
strcat(new_dest,dest);
strcat(new_dest,"/");
strcat(new_dest,src);
printf("new_dest = %s\n",new_dest);
if(rename(new_src,new_dest) != 0){
fprintf(stderr,"rename failed with error %s\n",strerror(errno));
}
free(new_src);
free(new_dest);
free(src);
free(dest);
exit(EXIT_SUCCESS);
}
编辑:为下面的描述添加了代码
最后,您将得到一个路径,该信息是给定参数是目录还是常规文件的信息以及该路径。如果源是常规文件,而目标是目录,则将路径与常规文件名,路径与目录名和常规文件名连接起来(您的源)
在......之外
Path = /home/foo
src = bar
dest = coffee
建立
new_src = /home/foo/bar
new_dest = /home/foo/coffee/bar
这样对
rename()
的调用就是rename(new_src, new_dest);
这样,您可以将常规文件重命名为
rename()
接受的常规文件。请注意,
rename()
不适用于每个文件系统,但不适用于大多数文件系统。关于c - 如何用C语言编写我自己的mv(重命名/移动)unix命令版本?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38426345/