Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 程序不正确地复制文件_C_File_Copy - Fatal编程技术网

C 程序不正确地复制文件

C 程序不正确地复制文件,c,file,copy,C,File,Copy,因此,对于我的Systems类中的赋值,我们必须创建一个程序,该程序在给定的源中获取一个文件,并使用三个copyfile()函数之一将其复制到给定的目标 在命令行中运行程序时,它将接受三个参数:./cptest、输入文件位置和输出文件位置,以及两个可选参数:要使用的copyfile()函数的编号以及缓冲区大小 如果copyfile()函数参数选择1,程序应使用格式化I/O(文件句柄)复制文件,然后一次复制一个字符 如果为copyfile()函数参数选择2,则程序应使用整数文件描述符复制文件,然后

因此,对于我的Systems类中的赋值,我们必须创建一个程序,该程序在给定的源中获取一个文件,并使用三个copyfile()函数之一将其复制到给定的目标

在命令行中运行程序时,它将接受三个参数:./cptest、输入文件位置和输出文件位置,以及两个可选参数:要使用的copyfile()函数的编号以及缓冲区大小

如果copyfile()函数参数选择1,程序应使用格式化I/O(文件句柄)复制文件,然后一次复制一个字符

如果为copyfile()函数参数选择2,则程序应使用整数文件描述符复制文件,然后一次复制一个字符

如果为copyfile()函数参数选择3,则程序应分配一个大小等于为buffer size参数输入的大小的缓冲区(例如1024),然后使用read()从输入文件中一次最多读取这么多字节

如果您没有输入第三个参数(copyfile()函数号),那么程序将自动使用copyfile3(),无论您使用第四个参数决定的缓冲区大小如何

如果未输入第四个参数(缓冲区大小),则程序将默认设置为1024,并在必要时使用它(copyfile1()或2()不需要)

在调用每个copyfile()函数之前和之后,程序使用gettimeofday()创建时间戳。然后,程序使用后时间戳和前时间戳之间的秒和微秒差创建一个新的时间戳,以确定复制所用的时间,然后打印出所有这些信息

例如,如果我输入:./cptest~/My_Documents/photo.JPG~/assig6/photo.JPG 3 程序应返回:

复制前的时间戳: 秒:1425150842,微秒:914511 复制后的时间戳: 秒:1425150842,微秒:927662 复制耗时0秒,13151微秒

既然你知道了这个程序的作用,让我们开始讨论这个问题。每次我使用copyfile()函数运行程序时,无论是1、2还是3,从技术上讲,复制都可以正常工作,文件最终到达正确的目的地,并且程序返回时间戳方面的所有正确信息

但是,实际上,它不起作用,因为当我使用copyfile1()时,它会复制所有字节,但当我尝试打开文件(例如a.jpg)时,它会说它无法查看该文件,因为它似乎已损坏、损坏或太大。当我使用copyfile2()和copyfile3()时,目标中的文件只有1KB,当我不传入第三个或第四个参数时,输出文件有0KB。word文档也会发生同样的情况

是否有原因可以复制文件,但文件在复制过程中被损坏?代码似乎是对的,但最终结果却不是

以下是主文件cptest.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include "cptest.h"

/** cptest.cpp
 * A file copying program.
 * Derived partially from caesar.cpp by Horstmann and Budd from big C++
 */

/** Prints usage instructions.
 * @param program_name the name of this program
 */
void usage(char* program_name) {  
  // Prints out usage instructions if incorrect number of parameters is passed in
  printf("Usage: %s infile outfile copy_function_number buffer_size \n", program_name);
}

/** Prints file opening error message
 * @param filename the name of the file that could not be opened
 */
void open_file_error(char* filename) {  
  // Error message if unable to open the file
  printf("Error opening file %s\n", filename);
}

/** Main program: copies a file.
 * @param argc Number of command-line arguments (including program name).
 * @param argv Array of pointers to character arays holding arguments.
 * @return 0 if successful, 1 if failure.
 */
int main(int argc, char* argv[]) {  
  char* infilename; // Name of input file
  char* outfilename; // Name of output file
  int copy_function_number; // Chooses which copy function is used based on argv[3]
  int buffer_size; // Size of buffer
  int returnstatus; // 0 or 1 depending on success or failure to copy the file to the destination
  struct timeval* before = malloc(sizeof(struct timeval)); // Struct for time before copying is done
  struct timeval* after = malloc(sizeof(struct timeval)); // Struct for time after copying is done

  if (argc != 3 && argc != 4 && argc != 5) {
    usage(argv[0]); // Must have 2, 3, or 4 arguments in addition to ./cptest.
    return 1; // Failure!
  }

  infilename = argv[1]; // Sets first parameter to the input file name
  outfilename = argv[2]; // Sets second parameter to the output file name

  if(argv[3] == NULL) {
    copy_function_number = 3; // Program uses copyfile3 if no third parameter is entered
  }

  else {
    copy_function_number = atoi(argv[3]); // Otherwise program uses whatever function is passed by third parameter
  }

  if (argv[4] == NULL) {
    buffer_size = 1024; // Sets buffer size to 1024 if no fourth parameter is entered
  }

  else {
    buffer_size = atoi(argv[4]); // Otherwise buffer size is whatever user enters as fourth parameter
  }

  if (copy_function_number == 1) {
    gettimeofday(before, NULL); // Get timestamp before the copying
    // Perform the copying with copyfile1() if the third parameter is 1
    returnstatus = copyfile1(infilename, outfilename); 
    gettimeofday(after, NULL); // Get timestamp after the copying
  }

  if (copy_function_number == 2) {
    gettimeofday(before, NULL); // Get timestamp before the copying
    // Perform the copying with copyfile2() if the third parameter is 2
    returnstatus = copyfile2(infilename, outfilename);  
    gettimeofday(after, NULL); // Get timestamp after the copying
  }

  if (copy_function_number == 3) {
    gettimeofday(before, NULL); // Get timestamp before the copying
    // Perform the copying with copyfile3() if the third parameter is 3
    returnstatus = copyfile3(infilename, outfilename, buffer_size);  
    gettimeofday(after, NULL); // Get timestamp after the copying
  }

  else {
    if (copy_function_number != 1 || copy_function_number != 2 || copy_function_number != 3 || argv[3] == NULL) {
      gettimeofday(before, NULL); // Get timestamp before the copying
      // Perform the copying with copyfile3() if no third parameter is entered
      returnstatus = copyfile3(infilename, outfilename, buffer_size);  
      gettimeofday(after, NULL); // Get timestamp after the copying
    }
  }

  struct timeval *copytime = difference_in_time(before, after); // Struct for time after copying is done

  // Print out information of the timestamp before copying
  printf("Timestamp Before Copying: \n Seconds: %d, Microseconds: %d\n", before->tv_sec, before->tv_usec);
  // Print out information of the timestamp after copying
  printf("Timestamp After Copying: \n Seconds: %d, Microseconds: %d\n", after->tv_sec, after->tv_usec);
  // Print out information of the difference between the timestamps (how long the copying took)
  printf("Copying took %d seconds, %d microseconds\n", copytime->tv_sec, copytime->tv_usec);

  return returnstatus; // 0 if successful copy, 1 if unsuccessful.
}

/** Copies one file to another using formatted I/O, one character at a time.
 * @param infilename Name of input file
 * @param outfilename Name of output file
 * @return 0 if successful, 1 if error.
 */
int copyfile1(char* infilename, char* outfilename) {
  FILE* infile; //File handle for source.
  FILE* outfile; // File handle for destination.

  infile = fopen(infilename, "r"); // Open the input file.
  if (infile == NULL) {
    open_file_error(infilename); // Error message if there was a problem opening the input file.
    return 1; // Failure!
  }

  outfile = fopen(outfilename, "w"); // Open the output file.
  if (outfile == NULL) {
    open_file_error(outfilename); // Error message if there was a problem opening the output file.
    return 1; // Failure!
  }

  int intch;  // Character read from input file. must be an int to catch EOF.
  unsigned char ch; // Character stripped down to a byte.

  // Read each character from the file, checking for EOF.
  while ((intch = fgetc(infile)) != EOF) {
    ch = (unsigned char) intch; // Convert to one-byte char.
    fputc(ch, outfile); // Write out.
  }

  fclose(infile); // Close the input file.
  fclose(outfile); // Close the output file.

  return 0; // Success!
}

/** Copies one file to another using integer file descriptors instead of file handles, one character at a time.
 * @param infilename Name of input file
 * @param outfilename Name of output file
 * @return 0 if successful, 1 if error.
 */
int copyfile2(char* infilename, char* outfilename) {
  int infile; //File handle for source.
  int outfile; // File handle for destination.
  // Allocates a buffer for the chars that will be read from the input and written to the output.
  char buffer[1024]; 

  infile = open(infilename, O_RDONLY); // Open the input file.
  if (infile < 0) {
    open_file_error(infilename); // Error message if there was a problem opening the input file.
    return 1; // Failure!
  }

  outfile = open(outfilename, O_WRONLY | O_CREAT); // Open the output file.
  if (outfile < 0) {
    open_file_error(outfilename); // Error message if there was a problem opening the output file.
    return 1; // Failure!
  } 

  int intchin;  // Character read from input file. must be an int to catch EOF.
  int intchout; // Character written to the output file. must be an int to catch EOF.
  // Size of the buffer so that when you are copying extremely large files, it does not have to go through 200000 loop iterations
  int buffer_size = 1024; 
  unsigned char ch; // Character stripped down to a byte.

  // Read each character from the file, checking for 0.
  while ((intchin = read(infile, buffer, buffer_size)) != 0) {
    ch = (unsigned char) intchin; // Convert to one-byte char.
    intchout = write(outfile, buffer, ch); // Write out.
  }

  close(intchin); // Close the input file.
  close(intchout); // Close the output file.

  return 0; // Success!
}

/** Copies one file to another using integer file descriptors, buffer_size characters at a time.
 * @param infilename Name of input file
 * @param outfilename Name of output file
 * @param buffer_size Size of the buffer for reading and writing
 * @return 0 if successful, 1 if error.
 */
int copyfile3(char* infilename, char* outfilename, int buffer_size) {
  int infile; //File handle for source.
  int outfile; // File handle for destination.
  // Allocates a buffer of size buffer_size for the chars that will be read from the input and written to the output.
  char* buffer = (char*) malloc(sizeof(char)* buffer_size); 

  infile = open(infilename, O_RDONLY); // Open the input file.
  if (infile < 0) {
    open_file_error(infilename); // Error message if there was a problem opening the input file.
    return 1; // Failure!
  } 

  outfile = open(outfilename, O_WRONLY | O_CREAT); // Open the output file.
  if (outfile < 0) {
    open_file_error(outfilename); // Error message if there was a problem opening the output file.
    return 1; // Failure!
  } 

  int intchin;  // Character read from input file. must be an int to catch EOF.
  int intchout; // Character written to the output file. must be an int to catch EOF.
  unsigned char ch; // Character stripped down to a byte.

  // Read each character from the file, checking for 0.
  while ((intchin = read(infile, buffer, buffer_size)) != 0) {
    ch = (unsigned char) intchin; // Convert to one-byte char.
    intchout = write(outfile, buffer, ch); // Write out.
  }

  close(intchin); // Close the input file.
  close(intchout); // Close the output file.
  free(buffer); // Free the buffer that was allocated.

  return 0; // Success!
}

/** Makes a new timeval struct that determines the difference between two timestamps
 * @param time1 Struct containing the information for the first timestamp
 * @param time2 Struct containing the information for the second timestamp
 * @return The struct made using the two parameters
 */
struct timeval* difference_in_time(struct timeval* time1, struct timeval* time2) {
  struct timeval* copytime = malloc(sizeof(struct timeval)); // Allocates a struct to hold the difference between the two timestamps.

  if ((time2->tv_sec - time1->tv_sec) < 0) {  
    // Error message for if the first timestamp entered was before the second timestamp.
    printf("Seconds value is negative! time1 should be before time2!\n"); 
  }

  if ((time2->tv_usec - time1->tv_usec) < 0) {
    // Handles if the difference in microseconds between the second and first timestamps would be negative, subtracting 1 from the seconds.
    copytime->tv_sec = (time2->tv_sec - time1->tv_sec) - 1; 
    // Handles if the difference in microseconds between the second and first timestamps would be negative, subtracting the difference from 1000000.
    copytime->tv_usec = 1000000 - (time2->tv_usec - time1->tv_usec); 
  }

  else {
    // Otherwise the seconds for the third timestamp is the difference between the seconds of the second and first timestamps.
    copytime->tv_sec = (time2->tv_sec - time1->tv_sec); 
    // Otherwise the microseconds for the third timestamp is the difference between the microseconds of the second and first timestamps.
    copytime->tv_usec = (time2->tv_usec - time1->tv_usec); 
  }

  return copytime; // Return the new timestamp created.
}
下面是生成文件:

cptest: cptest.o
    gcc -g cptest.o -o cptest

cptest.o: cptest.c cptest.h
    gcc -c -g cptest.c

clean:
    rm -f *.o cptest

docs:
    doxygen
    chmod a+r html/*
    cp -p html/* ~/public_html/cs2303assig6
编辑:我想使用我们需要包含在程序中的readme.txt作为示例,向您展示所发生的事情可能会更容易。将其缩短为有用的信息,这样您就不必通过更多的文本墙

原件:

Name: *My name*
Section: CS2303 C01

What Program Does: *Explanation of what program does*

Example: *Example of what should show up when running program in the command line*

Results: *Test data for time it took for each function and using different buffer sizes to find most efficient function and buffer size*

Compiling:

To compile the code, use 'make' in the command line. The makefile should already link all of the .o files to the executable, so the work is done for you.
使用copyfile1()时的结果:

使用copyfile2()和3()时的结果:


copyfile2和3完全被破坏,因为它们将读取的字符数转换为一个字符。由于缓冲区大小通常为1024,此强制转换的结果为0,因此不会写入任何内容


对于copyfile 1,我建议使用二进制标志(“rb”或“wb”)打开文件,尽管我不认为这是问题所在。

奇怪的是,我们的教授给了我们copyfile 1,因此除非他搞砸了,否则应该正确复制文件。我刚刚检查过,使用rb和wb不会改变任何事情。我应该如何修复2和3,使其不会给出0的结果?首先,不要从读取中强制转换返回值-它是一个整数,在传递到写入时应保持原样(事实上,它应该是size\t,但现在int可以)。当我取出ch=(unsigned char)intchin并使intchout=write(outfile,buffer,intchin)时,当我运行它时,它从未真正完成执行(或者它需要很长时间才能复制,我只是没有耐心:P)。没关系。修复了我取出ch部分时出现的一些愚蠢错误,因此现在copyfile1和3似乎可以正常工作,copyfile2可以与jpgs一起工作,但在我使用自述文件作为文件时,会将有关时间戳的信息添加到自述文件的末尾。修复了关闭文件时出现的错误,因此现在所有功能都可以正常工作:)谢谢帮助!
Name: *My name*
Section: CS2303 C01

What Program Does: *Explanation of what program does*

Example: *Example of what should show up when running program in the command line*

Results: *Test data for time it took for each function and using different buffer sizes to find most efficient function and buffer size*

Compiling:

To compile the code, use 'make' in the command line. The makefile should already link all of the .o files to the executable, so the work is done for you.
so the work is done for you.S2303 C01

What Program Does: *Explanation of what program does*

Example: *Example of what should show up when running program in the command line*

Results: *Test data for time it took for each function and using different buffer sizes to find most efficient function and buffer size*

Compiling:

To compile the code, use 'make' in the command line. The makefile should already link all of the .o files to the executable, so the work is done for you.
so the work is done for you.