需要帮助将c转换为c ++(简单错误但无法修复)

时间:2012-01-11 23:31:37

标签: c++

我有一个c ++作业。作业要求将c程序转换为c ++。 以下是问题:

  

您需要将以下C函数转换为C ++   功能,然后将其嵌入一个完整的程序并测试它。注意   该函数复制整数的二进制文件而不是文本   文件。程序必须接受参数(要复制的文件和   要从命令行复制到的文件。

/* ==================== cpyFile =====================

This function copies the contents of a binary file
of integers to a second file.
Pre fp1 is file pointer to open read file
fp2 is file pointer to open write file
Post file copied
Return 1 is successful or zero if error
*/
int cpyFile (FILE *fp1, FILE *fp2)
{
  /* Local Definitions */
  int data;

  /* Statements */
  fseek (fp1, 0, SEEK_END);
  if (!ftell (fp1))
  {
    printf ("\n\acpyFile Error : file empty\n\n");
    return 0;
  } /* if open error */
  if (fseek (fp1, 0, SEEK_SET))
    return 0;
  if (fseek (fp2, 0, SEEK_SET))
    return 0;

  while (fread (&data, sizeof (int), 1, fp1))
    fwrite (&data, sizeof (int), 1, fp2);
  return 1;
} /* cpyFile */

我尽了最大努力并设法转换它,但不幸的是,当我使用它时,我在复制后得到的文件是空的。以下是我的回答:

#include <fstream>
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
  if(argc!=3)
  {cerr<<"invalid number of arguments. must be 3."<<endl;exit(1);}

  fstream fp1(argv[1],ios::in);
  if(!fp1)+{cerr<<argv[1]<<" could not be opened"<<endl;exit(1);}

  fstream fp2(argv[2],ios::out);
  if(!fp2)+{cerr<<"file could not be found."<<endl;exit(1);}


  int data;

  fp1.seekg (0,ios::end);
  if (!fp1.tellg ())
  {
    cout<<"\n\acpyFile Error : file empty\n\n";
    return 0;
  } /* if open error */
  if (fp1.seekg (0, ios::beg))
    return 0;
  if (fp2.seekg (0, ios::beg))
    return 0;

  while (fp1.read (reinterpret_cast<char*>(&data), sizeof (int)))
  {
    fp2.seekp(0);
    fp2.write (reinterpret_cast<char*>(&data), sizeof (int));
  }
  return 1;
}

我尽了最大努力,一切正常,但是当我复制二进制文件时,我得到的文件是空的,我不知道为什么。

5 个答案:

答案 0 :(得分:7)

正如其他人所说,你需要以二进制模式打开文件

fstream fp1(argv[1], ios::in | ios::binary); // combine ios::in with ios::binary

fstream fp2(argv[2], ios::out | ios::binary); // combine ios::out with ios::binary

或者您可以将它们ifstream(文件流中的 仅供阅读使用)和ofstream输出文件流,仅供写入)并删除ios::inios::out,因为ifstream隐含ios::inofstream隐含ios::out

ifstream fp1(argv[1], ios::binary);

ofstream fp2(argv[2], ios::binary);

您需要执行此操作,因为如果您不这样做,则在您阅读或写入文件时会翻译该文件,例如将行结尾从\r\n\r转换为{{{ 1}}等,这会弄乱你的二进制数据,这些数据可能碰巧有这些字节。

此:

\n

将永远使代码返回,因为if (fp1.seekg (0, ios::beg)) return 0; if (fp2.seekg (0, ios::beg)) return 0; 返回您调用它的对象。在这方面,它不等同于seekg因为fseek在成功时返回0。所以你永远不会进入fseek循环。从while语句中取出它们,使它看起来像这样:

if

或者如果你必须进行检查,你想做

fp1.seekg(0, ios::beg);
fp2.seekg(0, ios::beg);

此外,这(在if (!fp1.seekg (0, ios::beg)) // notice the added ! return 0; if (!fp2.seekg (0, ios::beg)) // notice the added ! return 0; 内):

while

将要写入的点设置到文件的开头。因此,除了文件的开头,你永远不会写任何东西。只需完全删除该行。

此外,循环内部有一个fp2.seekp(0); ,使其在第一次迭代时返回。将return移到循环外部,这样您只能在循环结束后返回。没关系,因为不寻常的支撑样式而误读。

答案 1 :(得分:1)

每当您从fp1读取新数据块时,您都会将fp2快退到流的开头,实质上会丢弃您已写入fp2的内容。尝试将fp2.seekp(0)移出主循环。

答案 2 :(得分:1)

你有一些问题。我首先要解决这个问题:

if (fp1.seekg (0, ios::beg))
    return 0;
if (fp2.seekg (0, ios::beg))
    return 0;

seekg方法返回对其调用的istream的引用,因此上述内容与此相同:

fp1.seekg (0, ios::beg);
if (fp1) // i.e., if fp1 is in a valid state (as opposed to e.g. end-of-file)
    return 0;
fp2.seekg (0, ios::beg);
if (fp2) // i.e., if fp2 is in a valid state (as opposed to e.g. end-of-file)
    return 0;

这显然不是你想要的。

要调试代码,可以使用std::cout << "Got to line " << __LINE__ << std::endl;之类的语句来确定程序的哪些部分实际运行。那很快就会发现上述问题。

答案 3 :(得分:0)

二进制文件需要在二进制模式下专门打开,所以如果你有fstream fp1(argv[1],ios::in);,你也应该像这样添加一个ios :: binary:fstream fp1(argv[1], ios::in | ios::binary);

答案 4 :(得分:0)

在C ++代码中,在写入每个数字之前,您正在寻找输出文件的开头,因此输出文件最多只能有2个字节。