c++读取文件中字符,不过滤空白符

来源:互联网 发布:博然视频监控 软件 编辑:程序博客网 时间:2024/05/16 03:40
1)问题描述

C++读取一个文本文件时,直接用流的 >> 方法会自动把空白符作为输入的分界符,所以如下代码存在问题

[cpp] view plain copy
  1. ifstream infile("xxx.txt",ios::in);  
  2. while(!infile.eof()){  
  3.     infile>>c;  
  4.     while( (c!=' ') && (c!='\t') && (c!='\n') ){  
  5.         word[pos]=c;  
  6.         pos++;  
  7.         infile>>c;  
  8.     }  
  9.     word[pos]='\0';  
  10.   
  11.     if(pos!=0){  
  12.         cout<<word<<endl;  
  13.     }  
  14.     pos=0;  
  15. }  


比如有test.txt文件

my name is zhccl


当用 infile>>c 读到 "my" 的 “y” 之后,下一个会自动滤过 空格符 因为空格符是作为一个标准输入的非有效字符,下一次会读入 ”n“ 所以整段代码会读入word=”mynameiszhccl“

并不会分别读到 my,name,is,zhccl


2)解决方案

1.用 infile.getline(),来解决,一次读到一个 "\n" 为止,再来用空白符作为分界符来解释  word[] 

2.用 infile>>noskipws; 来强制读入每一个字符,不过滤空白符,包括换行符。


代码如下:


[cpp] view plain copy
  1. /* 
  2.  * 从文件中读取字符,不忽略空白符 
  3.  * cc 20120904 
  4.  */  
  5. #include <iostream>  
  6. #include <fstream>  
  7. using namespace std;  
  8.   
  9. int main(){  
  10.     ifstream infile("d:\\f2.txt",ios::in); //以输入方式打开文件  
  11.         //判断是否打开成功  
  12.         if(!infile) {  
  13.         cerr<<"open error!"<<endl;  
  14.         exit(1);  
  15.     }  
  16.       
  17.     char c;  
  18.     int pos;  
  19.     char word[50];  
  20.     //从文件逐个读取字符存放到c中,最终放到word数组中  
  21.     pos=0;  
  22.   
  23.     //不忽略空白符,也不忽略每行最后那个'\n'  
  24.     infile>>noskipws;  
  25.   
  26.     while(!infile.eof()){  
  27.         infile>>c;  
  28.         while( (c!=' ') && (c!='\t') && (c!='\n') ){  
  29.             word[pos]=c;  
  30.             pos++;  
  31.             infile>>c;  
  32.         }  
  33.         word[pos]='\0';  
  34.   
  35.         if(pos!=0){  
  36.             cout<<word<<endl;  
  37.         }  
  38.         pos=0;  
  39.     }  
  40.   
  41.     infile.close();  
  42.     return 0;  
  43. }  

这儿有点问题,就是文件最后必须是一个 ”\n“ ,否则程序会崩溃,我正在纳闷这一点。

持续更新:

找到原因了,在文件  test.txt 

my name is zhccl

当准备读 ”zhccl“ 时,此时while(!infile.eof())判断通过,然后会一直读,infile>>c 知道已经读到文件结尾了,此时infile=0,我们并没有去验证inflie是否到末尾,所以c的值保持前一次读入字符 ”l“ ,并不从文件读入字符来更新,即最后一个读入的字符串为”zhccllllllllllll.....“ 直到 word[] 溢出,出错。

改正方法:

检查infile情况

[cpp] view plain copy
  1. while(!infile.eof()){  
  2.     infile>>c;  
  3.     while( (c!=' ') && (c!='\t') && (c!='\n') ){  
  4.         word[pos]=c;  
  5.         pos++;  
  6.         if( (infile>>c)==0){  
  7.             break;  
  8.         }  
  9.     }  
  10.     word[pos]='\0';  
  11.     pos=0;  
  12. }  

或者二次检查是否到文件结束

[cpp] view plain copy
  1. while(!infile.eof()){  
  2.     infile>>c;  
  3.     while( (c!=' ') && (c!='\t') && (c!='\n') && (!infile.eof())){  
  4.         word[pos]=c;  
  5.         pos++;  
  6.     }  
  7.     word[pos]='\0';  
  8.     pos=0;  
  9. }