以相反的顺序复制文件的内容

时间:2014-12-20 20:42:19

标签: c

我需要编写一个程序,将文件内容复制到另一个文件并进行反转。 我找到了一个例子,并通过阅读来了解发生了什么。 问题是我的程序必须使用两个函数:

void reverse(char line[]){
   int i;
   int length;
   char tmp;
     ..
     ..
     ..
   return;
}

(没有进一步的参数或局部变量)

第二个功能完成剩下的工作(打开文件,复制文件,关闭文件) 主程序只读取文件的名称并调用复制功能。

#include<stdio.h>
#include<string.h>

void reverse(char line[])
{
    int  i;
    int  length;
    char temp;
    if (line == NULL)
        return;
    length = strlen(line);
    for (i = 0 ; i < length / 2 + length % 2 ; ++i)
    {
        if (line[i] == line[length - i - 1])
            continue;
        temp                 = line[i];
        line[i]              = line[length - i - 1];
        line[length - i - 1] = temp;
    }
    return;
}




 int main() 
{ 

    FILE *src_fh, *dst_fh; 
    char src_fn[256+1], dst_fn[256+1]; 


    printf("Enter Source File Name:\n"); 
    fgets(src_fn, sizeof(src_fn), stdin); reverse(src_fn); 


    if( (src_fh = fopen(src_fn, "r")) == NULL ) 
    { 
        printf("ERROR: Source File %s Failed To Open...\n",src_fn); 
        return(-1); 
    } 


    printf("Enter Destination File Name:\n"); 
    fgets(dst_fn, sizeof(dst_fn), stdin); reverse(dst_fn); 


    if( (dst_fh = fopen(dst_fn, "w+")) == NULL ) 
    { 
        fclose(src_fh); 
        printf("ERROR: Destination File %s Failed To Open...\n",dst_fn); 
        return(-2); 
    } 

    int ch; 
    while( (ch = fgetc(src_fh)) != EOF ) 
    { 
        fputc(ch, dst_fh); 
    } 


    fclose(src_fh); 
    fclose(dst_fh); 
    return 0; 
}

3 个答案:

答案 0 :(得分:1)

原型line中的参数名称void reverse(char line[])似乎给出了一个提示,即如何解决给定的练习。

  1. 将文件分成行
  2. 反转每一行
  3. 颠倒行的顺序
  4. 然而,如果您的文件可能包含任何数据,那么您应该注意遵循此策略,因为仍然存在非常讨厌的问题。

    在这种情况下,你很难找到line[]的结尾,因为'\ 0'终止可能会与行中的文字'\ 0'混淆。

    作为一种解决方法,您可能会尝试用序列'\ 0''x'替换'/ 0'的任何文字出现,并在序列'\ 0'' - '之前标记行的结尾或者传递之前的任何内容在将反向行写入文件后,将其移至reverse()并重新替换替换。

    不幸的是,这种尝试看起来并不太优雅,但也许按照练习中的方式反转文件并不是很优雅。

答案 1 :(得分:1)

您只需将第一个字符与最后一个字符交换,第二个字符与前一个字符交换,依此类推。

您实际上并不需要int temp变量,但由于它似乎是必需的,因此

void reverse(char line[])
{
    int  i;
    int  length;
    char temp;
    if (line == NULL)
        return;
    length = strlen(line);
    for (i = 0 ; i < length / 2 + length % 2 ; ++i)
    {
        if (line[i] == line[length - i - 1])
            continue;
        temp                 = line[i];
        line[i]              = line[length - i - 1];
        line[length - i - 1] = temp;
    }
    return;
}

这是一个改进版本,没有int temp,而是存储length / 2 + length % 2的结果,因此不会在每次迭代时重新计算

void reverse(char line[])
{
    int i;
    int length;
    int half;

    if (line == NULL)
        return;
    length = strlen(line);
    half   = length / 2 + length % 2;
    for (i = 0 ; i < half ; ++i)
    {
        if (line[i] == line[length - i - 1])
            continue;
        line[length]         = line[i];
        line[i]              = line[length - i - 1];
        line[length - i - 1] = line[length];
    }
    line[length] = '\0';
    return;
}

在交换时只使用终止'\0'字节的位置作为temp

对于第二个函数,使用fgets读取每一行并使用fprintf将其写入文件,只需记住从读取字符串中删除换行符,就可以使用{{1}为此发布的函数y,如果你不删除换行符,反转的行将在行的开头有换行符。

答案 2 :(得分:0)

the following code 
1) incorporates proper error checking
2) outputs each input line, reversed, to the output file.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* chomp(char* p)
{
    int len;
    if(!p) return(p);
    if( (len=strlen(p))<=0 ) return(p);
    if( p[len-1] == '\n' ) { p[--len] = '\0'; }
    if( p[len-1] == '\r' ) { p[--len] = '\0'; }
    return(p);
} // end function: chomp

int main()
{
    /* Create Usable Variables */
    FILE *src_fh = NULL;
    FILE *dst_fh = NULL;
    char src_fn[256+1] = {'\0'};
    char dst_fn[256+1] = {'\0'};
    char line[2048]    = {'\0'};

    /* Retrieve Source File Name From User */
    printf("Enter Source File Name:\n");
    if( NULL == (fgets(src_fn, sizeof(src_fn), stdin) ) )
    { // fgets failed
        perror("fgets for input file name failed" );
        exit(EXIT_FAILURE);
    }

    // implied else, fgets successful

    chomp(src_fn); // remove trailing newline characters

    /* Attempt Opening Source File For Reading */
    if( (src_fh = fopen(src_fn, "r")) == NULL )
    {
        perror( "fopen failed" );
        printf("ERROR: Source File %s Failed To Open...\n",src_fn);
        return(-1);
    }

    // implied else, fopen source file successful

    /* Retrieve Destination File Name From User */
    printf("Enter Destination File Name:\n");
    if( NULL == (fgets(dst_fn, sizeof(dst_fn), stdin) ) )
    { // then fgets failed
        perror( "fgets for output file name failed" );
        fclose(src_fh); // cleanup 
        exit( EXIT_FAILURE );
    }

    // implied else, fgets for output file name successful

    chomp(dst_fn); // remove trailing newline characters

    /* Attempt Opening Destination File For Writing */
    if( NULL == (dst_fh = fopen(dst_fn, "w")) )
    {
        perror( "fopen for output file failed" );
        fclose(src_fh); // cleanup
        printf("ERROR: Destination File %s Failed To Open...\n",dst_fn);
        return(-2);
    }

    // implied else, fopen for output file successful

    int index;
    /* Copy Source File Contents (reversed, line by line) to destination file */
    while( NULL != (fgets(line, sizeof(line), src_fh) ) )
    {
        chomp(line); // remove trailing newline characters
        index = strlen(line) - 1; // -1 because arrays start with offset 0
                                  // and strlen returns offset to '\0'

        // output reversed line to file
        while( index >= 0 )
        {
            fputc( line[index], dst_fh );
            index--;
        } // end while

        fputc( '\n', dst_fh );
    } // end while

    /* Close Files On Success */
    fclose(src_fh);
    fclose(dst_fh);
    return 0;
} // end function: main