C 创建用户使用fopen输入的任何文件的副本(fp,“wb”)

C 创建用户使用fopen输入的任何文件的副本(fp,“wb”),c,fwrite,fread,C,Fwrite,Fread,该文件的副本包含原始文件的所有内容,以及类似“\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\”的内容。此外,它给出了错误的txt文件,其他文件格式很容易得到复制。我之前也尝试过使用fread和fwrite,但没有出现任何问题。是不是有些东西我试错了。它说我打开的文件有一些无效字符,以防它是文本文件 char strr[1]; int e; bzero(strr,1); while((e=(fr

该文件的副本包含原始文件的所有内容,以及类似“\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\”的内容。此外,它给出了错误的txt文件,其他文件格式很容易得到复制。我之前也尝试过使用fread和fwrite,但没有出现任何问题。是不是有些东西我试错了。它说我打开的文件有一些无效字符,以防它是文本文件

  char strr[1];
  int e;
  bzero(strr,1);
  while((e=(fread(strr,1,1,fpp)))>0)
  {
    fwrite(strr,1,1,bck);
    i++;
  }
  if(e>0)
  {
    fclose(bck);
  }
我认为问题在于上面的代码。我也在添加整个代码。请不要评论多线程部分,我知道当我使用互斥时,它是无用的,并且不会减少任何时间。有很多工作要做。请你帮我解决上面的问题好吗。提前谢谢

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int counter;
static FILE * fpp;
static FILE * bck;
pthread_mutex_t lock;
int wc;
int flag;
int lent;
unsigned long fsize(char* file)
{
    FILE * f = fopen(file, "rb+");
    fseek(f, 0, SEEK_END);
    unsigned long len = (unsigned long)ftell(f);
    fclose(f);
    return len;
}
void* doSomeThing(void* arg)
{
  pthread_mutex_lock(&lock);
  char str; 
  int i=0;
  counter++;
  char buff[100];
  bzero(buff,100);
  char strr[1];
  int e;
  bzero(strr,1);
  while(((e=(fread(strr,1,1,fpp)))>0) || i<=lent)  
  {
    fwrite(strr,1,1,bck);
    i++;
   }
   if(e>0)
   {
     fclose(bck);
   }
  pthread_mutex_unlock(&lock);
  return NULL;
}

int main()

{
  int i = 0;
  int err;

  char filn[100];
  printf("\nEnter Filename:");
  scanf("%s",filn);
  unsigned long len= fsize(filn);   
  lent=(int) len;
  lent=lent/5;
  printf("%lu",len);
  char backf[100];
  printf("\nEnter Filename to copy");
  scanf("%s",backf);
  bck=fopen(backf,"wb+");
  fpp=fopen(filn,"rb+");
  pthread_t tid[6];
  pthread_t * temp;
  fseek(fpp, 0, SEEK_SET);
  if (pthread_mutex_init(&lock, NULL)!=0)
  {
      printf("\n mutex init failed\n");
      return 1;
   }
  for(i=0;i<6;i++)
  err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL);
  //if (err != 0);
  int j=0;
  for(j=0;j<6;j++)
  {
    pthread_join(tid[j], NULL);
  }
  printf("\n%d",wc-1);    
  pthread_mutex_destroy(&lock);
  //fclose(bck);
  fclose(fpp);
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
整数计数器;
静态文件*fpp;
静态文件*bck;
pthread_mutex_t lock;
int wc;
int标志;
内联;
无符号长fsize(char*文件)
{
FILE*f=fopen(文件“rb+”);
fseek(f,0,SEEK_END);
无符号长len=(无符号长)ftell(f);
fclose(f);
回程透镜;
}
void*doSomeThing(void*arg)
{
pthread_mutex_lock(&lock);
char-str;
int i=0;
计数器++;
字符buff[100];
b0(buff,100);
char-strr[1];
INTE;
bzero(strr,1);
而((e=(fread(strr,1,1,fpp)))>0)|i0)
{
fclose(bck);
}
pthread_mutex_unlock(&lock);
返回NULL;
}
int main()
{
int i=0;
INTERR;
char-filn[100];
printf(“\n输入文件名:”);
scanf(“%s”,filn);
无符号长长度=fsize(filn);
lent=(int)len;
lent=lent/5;
printf(“%lu”,len);
char-backf[100];
printf(“\n输入要复制的文件名”);
扫描频率(“%s”,背面);
bck=fopen(backf,“wb+”);
fpp=fopen(filn,“rb+”);
pthread_t tid[6];
pthread_t*temp;
fseek(fpp,0,SEEK_SET);
if(pthread\u mutex\u init(&lock,NULL)!=0)
{
printf(“\n互斥初始化失败\n”);
返回1;
}
对于(i=0;i
括号有错,应该是

while ((e=fread(strr,1,1,fpp))>0)
此外,缩进非常糟糕,一次读取/写入1个字节的效率非常低,让
fclose
依赖于
if(e>0)
是错误的,但这两者都不是问题的原因

括号 fread返回读取的记录数(在您的情况下,是字节数,因为记录大小为1)。似乎只要有一个字节,您就想继续读取。但是您的
e=(fread..)>0
首先比较,然后将比较结果分配给e。在这种情况下,这实际上是正常的,因为在这种特定情况下,fread可以返回1或0,并且当返回值不是1时,您希望循环停止。但通常情况下,这是一个错误的情况,因为人们希望在变量中返回值。因此,您的状态耳鼻喉科看起来不太对劲

压痕 现在已经修好了

一次读/写1字节 即使使用fread/fwrite提供的缓冲,速度也非常慢。处理大小适中的缓冲区块的速度要快得多。缓冲区的大小取决于您的硬件,但4K或8K是一个很好的开始。当然,在您的特定应用程序中,您可能希望给线程一些事情做,而不是只复制每个线程一大块的东西

使fclose依赖于(任何事物) 通常是错误的,除非(任何内容)==(fopen成功)。当您完成该文件并且不想再使用它时,请关闭它。句号

在您的例子中,当(e…>0)
时,您有一个
循环,然后一个
if(e>0)
将永远不会执行if条件中的部分,因为使用
e>0
将永远不会到达if。因此,您不会在任何地方关闭文件。(在本例中,这是一件好事,因为稍后的线程仍将访问它,但通常是一个错误)

线程 你原来的帖子根本没有提到pthread


在您使用它的方式中,您的第一个线程将执行复制操作;在此过程中,其他线程将卡在互斥锁中。在第一个线程释放互斥锁后,其他线程之一将开始尝试复制文件。此时,输入文件的文件指针位于EOF,第一个线程停止;下一个线程d将尝试读取更多数据,失败,并将未修改的、零初始化的strr写入备份文件。这种情况会一直重复,直到
iI不知道为什么极客在看到新手代码时会变成纳粹。记住,即使你曾经是noob。许多人,包括我在内,对新手没有问题,实际上也希望提供帮助——否则我们不会回答如此多的问题。然而,一个问题越不清晰、简洁、易读,就越难回答。这意味着,缺乏信息、难以阅读或在海报上没有表现出努力的问题,会让所有可能回答的人感到恼火。代码格式不完全是火箭科学,而是你的原始帖子(同时被编辑)不完整,格式不正确。这就是为什么我的回答比平时更严厉的原因。在我看来,这是一个好的、彻底的回答。它选择最重要的问题作为第一个问题,然后讨论代码中的其他问题。干得好,Guntram。我唯一可能做的就是使用一些3级标题(以
####
开头),而不是像
e这样的字母副标题)线程
,使其更易于阅读。因此,例如,
####线程
。完成。感谢您的输入,乔纳森。感谢您的时间和帮助Guntram。在阅读了fread的手册页之后,我早些时候发现了这些愚蠢的错误,并且在stackoverflow上提出了一个愚蠢的问题。我打算删除它,然后找到了它您的回答非常详细。非常感谢!前面两行的缩进被取消了。这是因为我交替使用了emacs和gedit。
while ((e=fread(strr,1,1,fpp))>0)