我想为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/

10-09 08:32
查看更多