65.9K
CodeProject 正在变化。 阅读更多。
Home

MergeFiles

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2016 年 6 月 4 日

CPOL

1分钟阅读

viewsIcon

10925

一个 C 函数, 用于将任意数量的文本文件的内容合并到一个字符分隔的变量宽度结果文件中

背景

前几天,QA中发布了以下问题:
如何在同一文件中并排合并两个包含两列的文件?[^]

我认为,这个描述可以抽象为“从多个文本文件形成一个字符分隔的变宽文件,使用每个文件的内容填充每一列”。

引言

我喜欢一个好的练习,特别是如果它能让我有机会展示我生疏的C语言技巧。因此,作为回应,我用我自己的方式编写了这样一个函数。

  • 我的函数接受一个包含任意数量的文件名的数组。
  • 它不会失败,而是报告文件打开错误,但否则将无法读取的文件视为为空。
  • 它接受一个字符序列作为列分隔符使用。
  • 一个参数指定是否包含包含文件名称的“标题行”。
  • 它不需要输入文件都具有相同的行数——当输入文件的数据用完时,将向输出写入“空”值。
  • 返回值是写入输出的总行数。

我还考虑添加一个功能,如果指定,它可以将值放在QUOTEs周围。另一个潜在的功能是过滤掉空行。

Using the Code

result = MergeFiles ( argc - 2 , argv [ 1 ] , argv [ 2 ] , "\t" , false ) ;

结果可能如下所示:

f:\>FileMerge CON A.txt B.txt C.txt
A.txt   B.txt   C.txt
AAAAA   BBBBB   CCCCC
AAAAA   BBBBB
AAAAA           CCCCC
AAAAA   BBBBB
AAAAA   BBBBB   CCCCC
        BBBBB
                CCCCC

                CCCCC

                CCCCC

f:\>

MergeFiles

这是该函数:

int
MergeFiles
(
  int   Count
,
  char* Dest
,
  char* Source[]
,
  char* Delimiter
,
  bool  Headers
)      
{
  int result = 0 ;
  
  FILE* dst ;
  
  if ( ( ( dst = fopen ( Dest , "w" ) ) ) == NULL )
  { 
    printf ( "\nError opening %s %d" , Dest , errno ) ;
    
    result = 0 - errno ;
  } 
  else
  {     
    int i ;      
    int j = 0 ;      
    
    FILE** src = (FILE**) calloc ( Count , sizeof(FILE*) ) ;
    
    if ( Delimiter == NULL )
    {
      Delimiter = "" ;
    }
                       
    for ( i = 0 ; i < Count ; i++ )
    {                  
      if ( Headers )
      {
        if ( i > 0 )
        {     
          fprintf ( dst , "%s" , Delimiter ) ;      
        }

        fprintf ( dst , "%s" , Source [ i ] ) ; 
      }
      
      if ( ( ( src [ i ] = fopen ( Source [ i ] , "r" ) ) ) == NULL )
      {
        printf ( "\nError opening %s %d" , Source [ i ] , errno ) ;
      }
      else
      {
        j++ ;
      }
    }  

    if ( Headers )
    {
      fputc ( '\n' , dst ) ;      
      
      result++ ;
    }
    
    while ( j > 0 )                    
    {                                    
      for ( i = 0 ; i < Count ; i++ )    
      {                                  
        if ( i > 0 )
        {
          fprintf ( dst , "%s" , Delimiter ) ;      
        }
         
        if ( src [ i ] != NULL ) 
        {                                
          while ( 1 )
          {            
            int c = getc ( src [ i ] ) ;
                      
            if ( c == '\n' )
            {
              break ;
            }
            else if ( c == EOF )
            {   
              fclose ( src [ i ] ) ;
              
              src [ i ] = NULL ;
              
              j-- ;
              
              break ;
            }   
            else
            {
              fputc ( c , dst ) ;
            }
          }
        }     
      }
      
      fputc ( '\n' , dst ) ;      
      
      result++ ;
    }

    free ( src ) ;

    fclose ( dst ) ;
  } 
    
  return ( result ) ;
}   

我手头唯一支持bool的C编译器是:

gcc version 3.2 (mingw special 20020817-1)

我使用了-std=gnu99开关。

历史

  • 2016-06-03:首次发布
© . All rights reserved.