科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件实例解析C++/CLI的输入与输出

实例解析C++/CLI的输入与输出

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

当使用标准C++编程时,我们已开始接触到两个主要的I/O\"工具\":标准C头文件cstdio和标准C++中与流相关的头文件iostream。

作者:谢启东编译 来源:天极开发 2007年11月14日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
文件I/O

  除我们上面使用的类之外,在文件I/O与标准流之间,其差异并不明显。例2中的程序从命令行中接受它的输入与输出文件名字符串:

  例2:

using namespace System;
using namespace System::IO;

void Copy(TextReader^ inStream, TextWriter^ outStream);

int main(array<String^>^ argv)
{
 if (argv->Length != 2)
 {
  Console::WriteLine("需要两个参数。");
  /*1*/ Environment::Exit(1);
 }

 try
 {
  /*2a*/ FileStream^ inFile = gcnew FileStream(argv[0], FileMode::Open);
  /*2b*/ StreamReader^ inStream = gcnew StreamReader(inFile);
  /*2c*/// StreamReader^ inStream = File::OpenText(argv[0]);

  Console::WriteLine("CanRead is {0}, CanWrite is {1}",inFile->CanRead, inFile->CanWrite);
 
  /*3*/ StreamWriter^ outStream = File::CreateText(argv[1]);
  /*4*/ Copy(inStream, outStream);
  /*5*/ outStream->Write("{0} * {1} = {2}\n", 10, 5, 10 * 5);
  inStream->Close();
  outStream->Close();
 }

 /*6*/ catch (FileNotFoundException^ ex)
 {
  Console::WriteLine(ex->Message);
 }

 /*7*/ catch (IOException^ ex)
 {
  Console::WriteLine(ex);
 }
}

/*8*/
void Copy(TextReader^ inStream, TextWriter^ outStream)
{
 int c;
 while ((c = inStream->Read()) != -1)
 {
  outStream->Write(static_cast<wchar_t>(c));
 }
}

  请留意main中的新符号,argv声明为指向字符串数组的句柄,与标准C++中main不同,这个数组中不包含代表程序名的字符串,而是在argv[0]中代表了第一个命令行参数。

  标记1中的Environment::Exit允许我们正常结束程序,并提供一个退出状态码(非零值在此表示没有成功)。在标记2a中,定义了一个FileStream类型的inFile引用变量,它对应于输入文件名,并指示创建一个新文件;接下来,在标记2b中,把这个FileStream对象映射到一个StreamReader对象上,这两步也可合为一步,如标记2c中所示(其已经被注释掉了)。另外,在File类中,提供了很多静态的函数,我们在标记3中使用了一个函数创建一个StreamWriter对象。

  正如上个例子一样,Copy将把输入中的每个字符复制到输出中。因为StreamReader是从TextReader中派生,而StreamWriter是从TextWriter中派生的,所以Copy中的函数调用都是合法的,即使用同属的I/O函数。

  在标记5中,向输出流进行了一个格式化的写入,并关闭了两个流。

  请注意,标记6与7的catch块中的顺序是非常重要的,因为FileNotFoundException是从IOException中派生的,所以基类必须跟在派生类后面,否则,派生类的catch块将永远没有机会执行。

  除提供各种构造函数之外,StreamReader和StreamWriter也支持与TextReader和TextWriter相同的函数集。

  字符串I/O

  正像我们可以读写文件一样,我们也能对字符串进行读写,请看例3中的例子,插2是程序输出:

  例3:

using namespace System;
using namespace System::Text;
using namespace System::IO;

void Copy(TextReader^ inStream, TextWriter^ outStream);

int main()
{
 String^ str = "abcde";
 /*1*/ StringReader^ inStream = gcnew StringReader(str);
 /*2*/ StringWriter^ outStream = gcnew StringWriter;

 /*3*/ StringBuilder^ sb = outStream->GetStringBuilder();
 Console::WriteLine("Capacity is {0}", sb->Capacity);
 
 /*4*/ outStream->Write(static_cast<wchar_t>(inStream->Read()));
 //读写a
 outStream->Write('!'); // write a !
 outStream->Write(static_cast<wchar_t>(inStream->Read()));
 //读写b
 outStream->Flush();
 outStream->Write("Result = {0,4:0.##}", 10.0/3);
 //输出格式化文本
 /*5*/ Console::WriteLine(outStream); //调用StringWriter::ToString
 /*6*/ Copy(inStream, outStream);
 /*7*/ Console::WriteLine(outStream);
 /*8*/ Console::WriteLine(sb); //调用StringBuilder::ToString
 /*9*/ inStream->Close();
 outStream->Close();
}

void Copy(TextReader^ inStream, TextWriter^ outStream)
{
 int c;
 while ((c = inStream->Read()) != -1)
 {
  outStream->Write(static_cast<wchar_t>(c));
 }
}

  代码段2:例3的输出

Capacity is 16
a!bResult = 3.33
a!bResult = 3.33cde
a!bResult = 3.33cde

  正如大家在程序中所看到的,默认情况下,StringWriter的构造函数将创建一个未命名的StringBuilder用于进行文本的写入,这个对象默认大小为16;另外也可在构造函数中使用一个现有的StringBuilder。在两种情况下,底层的StringBuilder都是通过StringWriter::GetStringBuilder来访问的。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章