linux C++:c++流操作----->rdbuf()

我们使用STL编程的时候有时候会想到把一个流对象指向的内容用另一个流对象来输出,比如想把一个文件的内容输出到显示器上,我们可以用简单的两行代码就可以完成。 
ifstream infile("test.txt");
 
cout << infile.rdbuf();
 
上面的代码就把infile流对象中的流重定向到标准输出cout上,您可以在屏幕上看到test.txt的内容。
 
下面的例子来自MSDN,清晰的描述了rdbuf函数的使用方法

// basic_ios_rdbuf.cpp // compile with: /EHsc #include <ios> #include <iostream> #include <fstream> int main( ) { using namespace std; ofstream file( "rdbuf.txt" ); streambuf *x = cout.rdbuf( file.rdbuf( ) ); cout << "test" << endl; // Goes to file cout.rdbuf(x); cout << "test2" << endl; }
 
rdbuf函数有两种调用方法

basic_streambuf<Elem, Traits> *rdbuf( ) const; 

basic_streambuf<Elem, Traits> *rdbuf( basic_streambuf<E, T> *_Sb);
 
1)无参数。返回调用者的流缓冲指针。
 
2)参数为流缓冲指针。它使调用者与参数(流缓冲指针)关联,返回自己当前关联的流缓冲区指针。
 
     假如我们用C语言写一个文件复制程序,比如一个mp3文件,我们首先考虑的是C语言的文件输入输出功能,其思路是建一个指定大小缓冲区,我们从源文件中循环读取缓冲区大小的数据,然后写进目的文件。而在C++中,我们抛弃了这种用字符缓冲区的按字节复制的方法,因为这种方法看起来很繁琐,而且效率一点也不高。下面可以对比这两种方法(程序可以直接执行):
 
C:
 
#include<stdlib.h>
#include<stdio.h>
int main()
{
 char buf[256];
 FILE *pf1, *pf2;
 if((pf1 = fopen("1.mp3", "rb")) == NULL)
 {
  printf("源文件打开失败/n");
  return 0;
 }
 if((pf2 = fopen("2.mp3","wb")) == NULL)
 {
  printf("目标文件打开失败/n");
  return 0;
 }
 while(fread(buf,1,256,pf1), !feof(pf1))
 {
  fwrite(buf,1,256,pf2);
 }
 fclose(pf1);
 fclose(pf2);
 return 0;
 
}
 
在C++中:
 
#include<fstream>
#include<iostream>
using namespace std;
int main()
{
    fstream fin("1.mp3",ios::in|ios::binary);
    if(!fin.is_open())
 {
  cout << "源文件打开失败" << endl;
  return 0;
 }
    fstream fout("2.mp3",ios::out|ios::binary);
 if(! fin.is_open())
 {
  cout << "目标文件打开失败!" << endl;
  return 0;
 }
    fout<<fin.rdbuf();
    fin.close();
    fout.close();
    return 0;
}  

看起来是不是清晰多了呢,这就是C++中的流缓冲的威力了,程序通过把源文件的流重定向到关联到目的文件的流对象,通过 fout<<fin.rdbuf();一句代码就完成了在C语言中的循环读写缓冲区的功能,而且C++中使用的是底层的流缓冲,效率更高!


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 C++ 中的文件和字符串处理库来实现 pmap 命令的功能。具体实现步骤如下: 1. 打开 /proc/[pid]/maps 文件,其中 pid 为进程号,该文件记录了进程的内存映射情况。 2. 逐行读取文件内容,使用字符串分割函数将每行内容按空格分割为多个字符串。 3. 解析字符串数组,获取每个内存区域的起始地址、结束地址、权限等信息。 4. 根据选项 -x 和 -X,以不同的格式输出内存地址。 以下是一个简单的实现示例: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <cstring> using namespace std; void print_usage() { cout << "Usage: pmap [-x|-X] <pid>" << endl; } string read_proc_maps(int pid) { stringstream ss; ss << "/proc/" << pid << "/maps"; string filename = ss.str(); ifstream fin(filename); if (!fin.is_open()) { cerr << "Failed to open file " << filename << endl; exit(EXIT_FAILURE); } stringstream buffer; buffer << fin.rdbuf(); fin.close(); return buffer.str(); } void print_address(string addr, string perm, string offset, string path, bool xflag, bool Xflag) { stringstream ss; unsigned long long addr_val; ss << hex << addr; ss >> addr_val; if (xflag) { cout << setw(16) << setfill('0') << hex << addr_val << " " << path << endl; } else if (Xflag) { string symbol = ""; char cmd[1024]; sprintf(cmd, "addr2line -e /proc/%d/exe 0x%s | sed -n '2p' | awk '{print $2}'", getpid(), addr.c_str()); FILE* fp = popen(cmd, "r"); if (fp) { char buffer[1024]; if (fgets(buffer, sizeof(buffer), fp)) { symbol = buffer; symbol = symbol.substr(0, symbol.size() - 1); } pclose(fp); } cout << setw(16) << setfill('0') << hex << addr_val << " " << setw(30) << setfill(' ') << left << symbol << path << endl; } else { cout << addr << " " << perm << " " << offset << " " << path << endl; } } int main(int argc, char** argv) { if (argc < 2) { print_usage(); return EXIT_FAILURE; } bool xflag = false; bool Xflag = false; int pid; if (strcmp(argv[1], "-x") == 0) { xflag = true; pid = atoi(argv[2]); } else if (strcmp(argv[1], "-X") == 0) { Xflag = true; pid = atoi(argv[2]); } else { pid = atoi(argv[1]); } string content = read_proc_maps(pid); stringstream ss(content); string line; while (getline(ss, line)) { string addr, perm, offset, device, inode, path; istringstream iss(line); iss >> addr >> perm >> offset >> device >> inode; getline(iss, path); print_address(addr, perm, offset, path, xflag, Xflag); } return EXIT_SUCCESS; } ``` 可以在命令行中执行以下命令来测试该程序的功能: ```bash ./pmap <pid> # 显示进程的内存映射情况 ./pmap -x <pid> # 以十六进制显示地址 ./pmap -X <pid> # 以十六进制及符号名称的形式显示地址 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值