| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3652 人关注过本帖
标题:fread和fwrite字节不足怎么办?
只看楼主 加入收藏
faminxmu
Rank: 3Rank: 3
来 自:厦门
等 级:论坛游侠
帖 子:191
专家分:106
注 册:2008-4-23
结帖率:70%
收藏
 问题点数:0 回复次数:10 
fread和fwrite字节不足怎么办?
假如我们定义了个char[100];然后打开文件调用fread进行读操作再打开另外文件进行fwrite操作
那么我们的形式应该是
fread(a,100,1,in);
fwrite(a,100,1,out);
但是如果输入的文件的字节数不是100的倍数,则出现在输出文件内用乱码填充到100字节的倍数,也就是如果文件没有100个字节fread和fwrite也要强制读写100个字节吗?
搜索更多相关主题的帖子: fread fwrite 字节 
2008-12-06 13:14
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1705
专家分:4345
注 册:2007-12-27
收藏
得分:0 
用这个东西的时候就是需要你自己小心,时刻记住,你是程序员,不是用户,永远不要以为有什么事情交给机器做就万事大吉了。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2008-12-06 13:41
faminxmu
Rank: 3Rank: 3
来 自:厦门
等 级:论坛游侠
帖 子:191
专家分:106
注 册:2008-4-23
收藏
得分:0 
是啊,那有没有解决办法吗?假设我要一次读写100个字节,但是文件没有100个字节,因为你不可能时时刻刻知道文件的具体大小啊

在虚拟的世界中寻找目标。
2008-12-06 13:45
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1705
专家分:4345
注 册:2007-12-27
收藏
得分:0 
首先,你是可以知道文件大小的。
其次,如果你的文件大小不是100的整数倍,那就说明你使用fread函数不是最合适的。
由于不知道你具体要做什么,所以没法具体解决。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2008-12-06 13:50
iFreeBSD
Rank: 4
等 级:业余侠客
威 望:4
帖 子:474
专家分:236
注 册:2007-11-5
收藏
得分:0 
以下是引用forever74在2008-12-6 13:50的发言:

首先,你是可以知道文件大小的。
其次,如果你的文件大小不是100的整数倍,那就说明你使用fread函数不是最合适的。
由于不知道你具体要做什么,所以没法具体解决。

fread一般要定义好buffer,比如说用fread和fwrite写个copy程序。
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>

int main(int argc , char *argv[]) {
    
    FILE   * fpin , * fpout ;
    long   krd , kwt , index ;
    char   * buffer ;
    if (argc != 3) {
        fprintf(stderr , "\n%s %s %s\n" , 
        "Usage:" , "cp resourefile" ,"/path/targetfile") ;
        exit(1) ;
    }
    fpin = fopen(argv[1] , "rb") ;          
    fpout = fopen(argv[2] , "ab") ;   
      
    fseek(fpin , 0L , SEEK_END) ;
    index = ftell(fpin) ;
    fseek(fpin , 0L , SEEK_SET) ;
    buffer = (char *)malloc(index) ;
    assert(buffer) ;   
    
    while ((krd = fread(buffer , index , 1 , fpin)) ) {
            kwt = fwrite(buffer , index , 1 , fpout) ;
            if (kwt != krd) {
                perror("file copy error") ;
                exit(1) ;
            }         
    }
    fclose(fpin) ;
    fclose(fpout) ;
  return 0 ;
}


[[it] 本帖最后由 iFreeBSD 于 2008-12-6 16:52 编辑 [/it]]

without further ado, let’s get started
2008-12-06 15:03
faminxmu
Rank: 3Rank: 3
来 自:厦门
等 级:论坛游侠
帖 子:191
专家分:106
注 册:2008-4-23
收藏
得分:0 
何必那么麻烦呢,我用ftell和fseek函数可以求出文件具体大小,这样我可以具体知道最后文件剩下多少字节,我就可以另外出理这几个字节了

在虚拟的世界中寻找目标。
2008-12-06 19:38
forever74
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:CC
等 级:版主
威 望:58
帖 子:1705
专家分:4345
注 册:2007-12-27
收藏
得分:0 
而我的意思是说fread/fwrite的长项是用来读写类似于结构体数组这种按记录访问的二进制文件的,这种文件应该存放整数个记录,那么就没有剩下个小尾巴的问题。

如果需要处理的二进制文件不是这种形式,那么理智告诉我们,不应该去自找麻烦地套用这类函数,直接fgetc/fputc就好。
因为现代编译系统完全有能力在效率上优化你的程序。

对宇宙最严谨的描述应该就是宇宙其实是不严谨的
2008-12-06 19:56
faminxmu
Rank: 3Rank: 3
来 自:厦门
等 级:论坛游侠
帖 子:191
专家分:106
注 册:2008-4-23
收藏
得分:0 
之所以这样写是因为发现频繁的调用函数会明显降低程序运行效率,假如我处理的是一个很大很大的文件,如电影剪切那么程序运行的时间将太长,但是用fread/fwrite的好处是可以整块数据的处理速度明显可以加快,比如下面是我写的剪切歌曲的程序,程序可以达到期待目的,当然里面有许多可以优化的地方,比如把名字换成从外界出入,这样就可以剪切任何文件了而不用每次都到代码里改名字.注:1048576字节就是1M
#include<stdio.h>
#define size 1048576
main()
{
     char a[size],b[20];
     int i=1,fileSize,n;
     FILE *out,*in;
     in=fopen("jiaru.mp3","rb");
     if(!in) return;
     fseek(in,0,2);//文件指针移到结尾
     fileSize=ftell(in);//判断结尾的位置,也就是文件大小
     fseek(in,0,0);//再移到文件头
     n=fileSize/size;//求出数据的块数
     while(i<=n)
     {
               sprintf(b,"jiaru%d.mp3",i);
               out=fopen(b,"wb");
               fread(a,size,1,in);
               fwrite(a,size,1,out);
               fclose(out);
               i++;
               }//剪切
                  sprintf(b,"jiaru%d.mp3",i);//下面四行处理剩下的字节
                  out=fopen(b,"wb");
                  fread(a,fileSize-n*size,1,in);
                  fwrite(a,fileSize-n*size,1,out);
                  fclose(out);
                  fclose(in);
                  }

[[it] 本帖最后由 faminxmu 于 2008-12-6 21:36 编辑 [/it]]

在虚拟的世界中寻找目标。
2008-12-06 20:13
iFreeBSD
Rank: 4
等 级:业余侠客
威 望:4
帖 子:474
专家分:236
注 册:2007-11-5
收藏
得分:0 
原来你是要对文件进行分块。
用一个栈把文件进行分块。

without further ado, let’s get started
2008-12-07 20:10
iFreeBSD
Rank: 4
等 级:业余侠客
威 望:4
帖 子:474
专家分:236
注 册:2007-11-5
收藏
得分:0 
还是以上面的copy程序为例,稍改一下就可以实现你的剪切功能。
程序代码:
/*stack.h*/
#include  <stdio.h>
#include  <stdlib.h>
#include  <assert.h>
#include  <stdbool.h>

#ifndef   _STACK_H_ 
#define   _STACK_H_

typedef  long  FileSize ;
typedef  struct Node  * PtrToNode ;

typedef  struct Node {
         FileSize     item ;
         PtrToNode    next ;
}Node ;

typedef struct Stack {
        PtrToNode  top ; 
}Stack ;

PtrToNode MakeNode(void) ;
void     CreateStack(Stack * sp) ;
bool     IsStackEmpty(Stack * sp) ;
void     Push(Stack * sp , FileSize size) ;
FileSize Pop(Stack * sp) ;

#endif

程序代码:
/*stack.c*/
#include  "stack.h"

PtrToNode MakeNode(void) {
   
   static PtrToNode nptr = NULL ;
   nptr = (PtrToNode)malloc(sizeof(Node)) ;
   assert(nptr) ;
   nptr->next = NULL ;


 return nptr ;
}

void CreateStack(Stack *sp) {
     sp->top = MakeNode() ;

 return ;
}

bool IsStackEmpty(Stack * sp) {
  

 return sp->top->next == NULL ;

}

void Push(Stack * sp , FileSize size) {
     
     PtrToNode np ;
     sp->top->item = size ;
     np = MakeNode() ;
     np->next = sp->top ;
     sp->top = np ;


 return ;
}

FileSize Pop(Stack * sp) {
       
   PtrToNode  np ; 
   FileSize item ;
   np = sp->top->next ;
   item = np->item ;
   free(sp->top) ;
   sp->top = np ;


 return item ;
}

程序代码:
/*main.c*/
#include "stack.h"

#define   SPLSIZE   (1024 * 1024)              /*split base on 1 megabyte */           
#define   Prompt   "Please waitting...\r" 

int main(int argc , char *argv[]) {    
    
    char          * buffer ;
    FileSize      size , crd , cwt ; 
    Stack         stack ; 
    FILE          * fpsrc , * fptar ; 
    
    if (argc != 3) {
        fprintf(stderr , "\n%s%s\n" ,
         "Usage: " , "cp resourcefile /path/targetfile") ;
         exit(1) ;
    }
    
    CreateStack(&stack) ;
    fpsrc = fopen(argv[1] , "rb") ;
    fptar = fopen(argv[2] , "ab") ;
    fseek(fpsrc , 0L , SEEK_END) ;
    size = ftell(fpsrc) ;
    fseek(fpsrc , 0L , SEEK_SET) ;

    if (size % SPLSIZE) {
        Push(&stack , size % SPLSIZE) ;
        size -= size % SPLSIZE ;
    }
    while (size) {
        
           Push(&stack , SPLSIZE) ;
           size -= SPLSIZE ;
    }     
    
    while(!IsStackEmpty(&stack)) {
          printf(Prompt) ;
          size = Pop(&stack) ;
          buffer = (char *)malloc(size) ;
          crd = fread(buffer , size , 1 , fpsrc) ;
          cwt = fwrite(buffer , size , 1 , fptar) ;
          if (crd != cwt) {
              fprintf(stderr,"Copy file error\n") ;
              exit(1) ;
          }
          free(buffer) ;
         
    }
   fclose(fpsrc) ;
   fclose(fptar) ;
  return 0 ;  
}


[[it] 本帖最后由 iFreeBSD 于 2008-12-7 21:37 编辑 [/it]]

without further ado, let’s get started
2008-12-07 20:51
快速回复:fread和fwrite字节不足怎么办?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.093878 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved