zoukankan      html  css  js  c++  java
  • c++学习笔记---04---从另一个小程序接着说

    从另一个小程序接着说

     

    文件I/O

    前边我们已经给大家简单介绍和演示过C和C++在终端I/O处理上的异同点。

    现在我们接着来研究文件I/O。

    编程任务:编写一个文件复制程序,功能实现将一个文件复制到另一个文件。

    例如:fileCopy  sourceFile  destFile

    C语言版实例分析:fileCopy.c

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int main( int argc, char* argv[] )
     5 {
     6       FILE *in, *out;
     7       int ch;  // char
     8 
     9       if( argc != 3 )
    10       {
    11             fprintf( stderr, "输入形式: copyFile 源文件名 目标文件名 
    " );
    12             exit( EXIT_FAILURE );
    13       }
    14 
    15       if( ( in = fopen( argv[1], "rb") ) == NULL )
    16       {
    17             fprintf( stderr, "打不开文件: %s 
    ", argv[1] );
    18             exit( EXIT_FAILURE );
    19       }
    20 
    21       if( ( out = fopen( argv[2], "wb") ) == NULL )
    22       {
    23             fprintf( stderr, "打不开文件: %s 
    ", argv[2] );
    24             fclose( in );                                   // 记得擦屁股
    25             exit( EXIT_FAILURE );
    26       }
    27 
    28       while( (ch = getc(in)) != EOF ) // EOF == end of file
    29       {
    30             if( putc( ch, out ) == EOF )
    31             {
    32                   break;
    33             }
    34       }
    35 
    36       if( ferror( in ) )
    37       {
    38             printf("读取文件 %s 失败! 
    ", argv[1] );
    39       }
    40 
    41       if( ferror( out ))
    42       {
    43             printf("写入文件 %s 失败! 
    ", argv[2] );
    44       }
    45 
    46       printf("成功复制1个文件!
    ");
    47 
    48       fclose( in );
    49       fclose( out );
    50 
    51       return 0;
    52 }

    重点分析

    argc与argv[]

    在程序中,main 函数有两个参数,整型变量argc和字符指针数组argv[]。

    argc的含义是程序的参数数量,包含本身。

    argv[]的每个指针指向命令行的一个字符串,所以argv[0]指向字符串”copyFile.exe”。

    argv[1]指向字符串sourceFile,argv[2]指向字符串destFile。

    in和out是我们声明的两个文件指针,它们的类型都是FILE*,分别作为两个 I/O 流对象使用。

    if( argc != 3 ) 是为了确保程序参数个数的正确性。

    通过fopen()函数我们以二进制的形式按可读/可写方式打开两个文件并返回两个文件指针给in和out。

    为了确保文件成功打开,我们还对fopen()的返回值进行了检查,如果为成功打开,我们就向标准错误流stderr发送一条消息。

    getc() 函数一次从输入流(stdin) 读取一个字符,putc() 函数把这个字符写入到输出流(stdout)。

    当getc() 遇到文件结束标志的时候,函数就返回 EOF。EOF 是一个宏,在stdio.h中定义,其值为一个负整数,通常是 -1。

    EOF 事实上有两个含义:MSDN

    注意细节,getc() 的返回值是 int 类型哦,所以我们声明时应该是 int ch。而不是char ch。

    C++的文件操作

    由于我们这个C++ 的版本相对有点不同,对类和对象的应用比较多和烦,但是由于我们现在还没开始讲解类和对象,所以大家现在尽管“先用”,

    例子一:example1.cpp 

     1 #include <fstream>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8       ifstream in;
     9       
    10       in.open( "test.txt" );
    11       if( !in )
    12       {
    13             cerr << "打开文件失败" << endl;
    14         return 0;
    15       }
    16 
    17       char x;
    18       while( in >> x )
    19       {
    20             cout << x;
    21       }
    22 
    23       cout << endl;
    24       in.close();
    25 
    26       return 0;
    27 }
     

    从刚刚的例题我们得到的信息是C++ 由于有类的封装,很多东西都变得更加“仔细”了!

    上边的例题我们用到的是文件的读取类 ifstream。

    接着我们结合例题来说说文件的写入要用到的类 ofstream。

    例题二:example2.cpp

     1 #include <fstream>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8       ofstream out;
     9 
    10       out.open( "test.txt" );
    11       if( !out )
    12       {
    13             cerr << "´ò¿ªÎļþʧ°Ü!" << endl;
    14             return 0;
    15       }
    16 
    17       for( int i=0; i < 10; i++ )
    18       {
    19             out << i;
    20       }
    21       
    22       out << endl;
    23       out.close();
    24 
    25       return 0;
    26 }

    在前边两个例子中出现:

    ifstream in;

    in.open( “test.txt” );

    ofstream out;

    out.open( “test.txt” );

    它们都是用一个open 函数来完成打开文件的功能。当然,这不是唯一的方法,我们还可以这样实现。

    ifstream in( “test.txt” );

    ofstream out( “test.txt” );

    以上代码在创建一个ifstream 和ofstream 类的对象时,将文件的名字传递给它们的构造函数。

    暂时我们可以这么理解构造函数:就是对象默认使用的函数(方法)。

    那么这两种方法有什么区别吗?结论是没有区别!

    事实上它还可以接受不止一个参数!

    下边我们给出一个接受两个参数的实例:

    ifstream  in( char* filename, int open_mode)

    其中,filename 表示文件的名称,它是一个字符串; open_mode 表示打开模式,其值用来定义以怎样的方式打开文件(跟open的参数一样哈)。

    下面给出几种常见的打开模式:

    ios::in — 打开一个可读取文件

    ios::out — 打开一个可写入文件

    ios::binary — 以二进制的形式打开一个文件。

    ios::app — 写入的所有数据将被追加到文件的末尾

    ios::trunk — 删除文件原来已存在的内容

    ios::nocreate — 如果要打开的文件并不存在,那么以此参数调用open 函数将无法进行。

    ios::noreplece — 如果要打开的文件已存在,试图用open 函数打开时将返回一个错误。

    下边给出一个关于如何使用打开模式的例子。

    例子三:example3.cpp 

     1 #include <fstream>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8       ofstream out( "test.txt", ios::app );
     9 
    10       if( !out )
    11       {
    12             cerr << "打开文件失败!" << endl;
    13             return 0;
    14       }
    15 
    16       for( int i=10; i > 0; i-- )
    17       {
    18             out << i;
    19       }
    20 
    21       out << endl;
    22       out.close();
    23 
    24       return 0;
    25 }

    如果我需要的不只是一种打开模式,要多种并存怎么办呢?

    我们只需要使用 OR 操作符:“|”

     1 #include <fstream>
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 int main()
     7 {
     8       fstream fp("test.txt", ios::in | ios::out );
     9       if( !fp )
    10       {
    11             cerr << "打开文件失败!"<< endl;
    12             return 0;
    13       }
    14 
    15       fp << "IloveFishc.com!";
    16 
    17       static char str[100]; 
    18 
    19       fp.seekg(ios::beg);  //// 使得文件指针指向文件头 ios::end 则是文件尾。
    20       fp >> str;
    21       cout << str << endl;
    22 
    23       fp.close();
    24 
    25       return 0;
    26 }
  • 相关阅读:
    pcs7 opc 连接问题
    nuget 多个程序引用同一个库时,当个这个库更新时,引用的程序都要跟新,否则会在运行时出错
    nuget update FileConflictAction
    a
    C#版本
    .NET Framework版本与CLR版本之间的关系
    c# 将一种数组类型转成另一种数组类型
    tfs 清除缓存,在需要时
    java枚举和仿枚举
    java反射的用法
  • 原文地址:https://www.cnblogs.com/alimjan/p/7615080.html
Copyright © 2011-2022 走看看