C++学习——输入文件流遇空白符结束

参考文章:
C++菜鸟教程笔记1
C++菜鸟教程笔记5
C/C++中的标准泛空格符有哪些?
C++读取文件输入流读入空格换行
C++文件流关于读到空格停止
C++的get()函数使用详解
C++中换行endl和\n的区别
c/c++中输入输出处理 按分隔符(换行、逗号、空格等)读取

!!!写的不好的地方麻烦大佬指点下

#1. 遇到空白符换行

#include <iostream>
#include <fstream>
#include <string.h>
int main(void)
{
  std::fstream fs;
  fs.open("E:\\CodeField\\Code_Cpp\\C_Single\\csdn\\20211010\\src\\afile.dat", std::ios::trunc | std::ios::out);
  if (!fs)
  {
    std::cout << "open afile.dat err!" << std::endl;
    exit(-1);
  }
  char str[100];

  std::cout << "enter sentence 1 : ";
  std::cin >> str;
  fs << str;

  std::cout << "enter sentence 2 : ";
  std::cin >> str;
  
  // fs << str << std::endl; // =》 '\n' + end
  // fs << str << '\n';
  fs << str << '\t'; // !!!这边直接插空白符跟在 str(控制台输23)后面
  // fs << str << '\v';
  // fs << str << '\f';
  // fs << str << '\r';
  // fs << str << ' ';

  std::cout << "enter sentence 3 : ";
  std::cin >> str;
  fs << str;

  fs.close();

  // 读取文件a,并复制到b
  std::ifstream ifs;
  ifs.open("E:\\CodeField\\Code_Cpp\\C_Single\\csdn\\20211010\\src\\afile.dat");
  if (!ifs)
  {
    std::cout << "open afile.dat err!" << std::endl;
    exit(-1);
  }
  std::ofstream ofs;
  ofs.open("E:\\CodeField\\Code_Cpp\\C_Single\\csdn\\20211010\\src\\bfile.dat", std::ios::trunc);
  if (!ofs)
  {
    std::cout << "open bfile.dat err!" << std::endl;
    exit(-1);
  }
  int i = 0;
  while (ifs >> str)
  {
    std::cout << "chunk" << ++i << " : " << str << std::endl;
    ofs << str;
  }

  ifs.close();
  ofs.close();

  printf("--------------end--------------\n");
  return 0;
}

输出结果:

enter sentence 1 : 12
enter sentence 2 : 23
enter sentence 3 : 34
chunk1 : 1223
chunk2 : 34
--------------end--------------

发现文件输入流到空白符(’\t’)停止,并跳过。我不想跳过

文件afile.dat内容

1122 33

文件bfile.dat内容

112233

生成复制的文件(bfile.dat)不一样,丢了制表符

#2. 取消输出流默认的忽视空白符

默认忽视空白符,ifs >> str 我的理解是将空白符前面的文件流提取到变量str里,之后默认的将文件位置指针定位到空白符之后,实现跳过空白符的功能,while循环语句中的自增就有了 。

该方法可以取消输出流默认的忽视空白符

void std::ios_base::unsetf(std::ios_base::fmtflags __mask)
int i = 0;
ifs.unsetf(std::ios::skipws); // 取消默认的忽视空白字符

while (ifs >> str)
{

  std::cout << "chunk" << ++i << " : " << str << std::endl;
  ofs << str;
}

输出结果:

enter sentence 1 : 12
enter sentence 2 : 23
enter sentence 3 : 34
chunk1 : 1223
--------------end--------------

发现chunk1后,循环停了

#3. get()方法取字符

如果取消了,while循环语句的自增就没了,找个替代的,get方法。

int std::istream::get()
std::istream &std::istream::get(char &__c)

三参的就不列了

下面使用get()方法

int i = 0;
ifs.unsetf(std::ios::skipws); // 取消默认的忽视空白字符
while (ifs >> str)
{
  ifs.get();// 从ifs文件输入流中读取一个字符

  std::cout << "chunk" << ++i << " : " << str << std::endl;
  ofs << str;
}

执行结果:

enter sentence 1 : 12
enter sentence 2 : 23
enter sentence 3 : 34
chunk1 : 1223
chunk2 : 34
--------------end--------------

#4.取存空白符

while(ifs >> str) 做循环条件我没搞太懂,我把它放循环体了

int i = 0;
char ch = '\0';
ifs.unsetf(std::ios::skipws); // 取消默认的忽视空白字符
while (1)
{
  ch = ifs.get(); // 该函数会改变文件位置指针??
  if (ch == EOF)
  {
    std::cout << "read file is over!" << std::endl;
    break;
  }
  else if (ch == '\n' || ch == '\t' || ch == '\v' || ch == '\f' || ch == 'r' || ch == ' ')
  {
    std::cout << "it is a white-space character !!!" << std::endl;

    std::cout << "chunk" << ++i << " : " << ch << std::endl;
    ofs << ch;// 保存空白字符
  }
  else
  {
    ifs.seekg(-1, std::ios::cur); // 普通字符回位,中文字符这边会有问题
    std::cout << "ch : " << ch << std::endl;

    ifs >> str;// 这个放里面!!!
    std::cout << "chunk" << ++i << " : " << str << std::endl;
    ofs << str;
  }
}

运行结果:

enter sentence 1 : 12
enter sentence 2 : 23
enter sentence 3 : 34
ch : 1
chunk1 : 1223
it is a white-space character !!!
chunk2 :
ch : 3
chunk3 : 34
read file is over!
--------------end--------------

afile.dat

1223 34

bfile.dat

1223 34

发现制表符拷贝过去了

疑问

  1. while(ifs >> str), ifs >> str这作条件到底啥意思?#2处为啥执行一次循环体就停了?
  2. ifs.get() 从流中取一个字符是不是会改变文件位置指针?如果不是,#4中这样搞ifs.seekg(-1, std::ios::cur);,会不会有问题?

  1. std::fstream待试
  2. getline使用
  3. 中文文本文件读写
  4. 正则空白字符匹配
上一篇:C++ 核心编程 文件操作


下一篇:C++文件的随机读写