| 头文件 | 定义在头文件里的类 / 对象 | 补充说明 |
|---|---|---|
<istream> |
istream 类、 iostream 类 |
istream 类是所有输入流的基类 |
<ostream> |
ostream 类 |
ostream 类是所有输出流的基类 |
<iostream> |
cin 对象、 cout 对象 |
cin 是 istream 类的对象;cout 是 ostream 类的对象 |
<fstream> |
ifsream 类、 ofstream 类、 fstream 类 |
|
<sstream> |
istringstream 类、 ostringstream 类、 stringstream 类 |
*** istream 和 ostream 类似,以下以 ostream 展开说明。
ostream = output stream
int、char、bool ...STL 中定义了一个 ostream 类的对象:cout ,将数据送到标准输出流
以下是自定义实现 ostream 的方法:
class ostream {
public:
ostream& operator<< (int num) {
printf("%d", num);
return *this;
}
ostream& operator<< (const char* str) {
printf("%s", str);
return *this;
}
...... // 重载需要输出的类型
} cout; // 定义 ostream 类的对象
int main() {
cout << 21 << "happy" ; // 根据输出数据类型,调用不同的输出函数
return 0;
}
以下是在自定义类中重载流运算符的方法:
class MyClass {
public:
friend ostream& operator<< (ostream&, MyClass&);
......
}
ostream& operator<< (ostream& output, MyClass& x) {
output << ... ;
return outpur;
}
注意:第二个参数可以是不同形式,不一定是引用,如:T 、T& 、const T 、const T&
常用的格式化输出方式有:
#include <iomanip>
cout << fixed << 3 << " " << 3.14 << " " << 3.14159265;
/* 将小数的小数点固定为 6 位
输出结果:3 3.140000 3.141593 */
cout << setprecision(3) << 3.1415926 << 0.1054;
/* 设置有效数字
输出结果:3.14 0.105 */
cout << fixed << setprecision(2) << 3.1415;
/* fixed 和 setprecision 合用,可以设置小数点数位
输出结果:3.14 */
cout << setw(5) << 921;
/* 设置输出的宽度,一次只对一个输出有效
默认向右对齐 */
for(int i = 8; i <= 12; ++i) {
cout << setw(5) << setfill('*') << i;
}
/* 设置输出的宽度 + 空白处填满指定字符
输出结果:****8****9***10***11***12 */
cout << scientific << 2018.0 << " " << 0.0001;
/* 以科学计数形式输出
输出结果:2.018000e+03 1.000000e-04 */
以上的 fixed 、setprecision() 等,包括实现换行的 endl ,都是流操纵算子
借助辅助类,设置成员变量的类
一些实现方式有在标准中定义,一些没有,不同编译器的实现不同
setprecision 实现的示例:
class setprecision {
private:
int precision;
public:
setprecision(int p): precision(p) {}
friend class ostream;
}
class ostream {
private:
int precision;
public:
ostream& operator<< (const setprecision &m) {
precision = m.precision;
return *this;
}
} cout;
cout << setprecision(2);
// setprecision(2) 会构造一个 setprecision 类的对象,作为参数传入输出流的函数
endl 实现的示例:
class ostream {
......
ostream& endl(ostream& os) {
os.put('\n'); // 输出换行符
os.flush(); // 清空缓冲区
return os;
}
ostream& operator<< (ostream& (*fn)(ostream&)) {
return (*fn)(*this);
}
}
// 换行方法1:调用输出流+流操纵算子
cout << endl;
// 换行方法2:直接使用endl函数
endl(cout);
清空缓冲区的好处:减少外部读写次数、保证内容正确读写到文件
cout对象的唯一性定义重载流运算符 / 使用 cout 的方式:
所有重载流运算符都会返回引用
ostream&
ostream类的拷贝构造函数会手动进行删除ostream(const ostream& x) = delete; ostream(ostream&& x);
原因:
- 减少复制开销
- 只移动不复制,只使用一个全局对象
cout进行输出- 多个对象无法同步输出状态
| 类 | 名 | 功能 | 补充说明 |
|---|---|---|---|
ifstream |
文件输入流 | 从文件中读取数据 | 是 istream 的子类在编译期间已经解析完毕 性能较好,取代了 scanf ( scanf 是有写入非法内存的风险) |
ofstream |
文件输出流 | 将数据写入文件中 | 是 ostream 的子类 |
*** ifstream 和 ofstream 类似,以下以 ifstream 进行说明:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
// 打开普通文本文件
ifsream input("filename.txt");
// 以二进制形式打开文件
ifstream input("filename.bin", ifstream::binary);
// 确保文件正确打开才进行操作
if(input) {
...
}
// 操作完毕,关闭文件
input.close();
return 0;
}
判断是否到了文末
while(input) {
...
}
去除前导空格
input >> ws;
检查下一个字符,如果到了文末就停止
int c = input.peek();
if(c == EOF) break;
读取
int n;
input >> n;
string str;
input >> str;
getline(cin, str);
...
char sentence[1000];
input.getline(sentence, 1000);
stringstream
iostream 的子类基本使用方法
#include <sstream>
using namespace std;
int main() {
stringstream ss;
ss << "10"; // 将数据写进 ss 的 buffer
ss << "0 200"; // 会自动连接字符串
int a, b;
ss >> a >> b; // 从 buffer 读取数据,转换成 int
return 0;
}
暂存数据的空间,包含已读取和未读取的内容
可以用 ss.str() 来返回 buffer 内的内容(返回类型:string)
stringstream ss;
ss << "10"; // buffer内有【10】
ss << "0 200"; // buffer内有【100 200】
int a, b;
ss >> a; // a = 100,buffer内有【100 200】
ss >> b; // b = 200,buffer内有【100 200】
ss.str(""); // 清空 buffer
从以上代码可见,buffer 内的内容不会因为被读取而减少
template<class outtype, class intype>
outtype convert(intype val) {
static stringstream ss; // 避免重复初始化
ss.str(""); // 清空 buffer
ss.clear(); // 清空状态位
ss << val;
outtype result; // 定义要转换的类型的变量
ss >> result;
return result; // 返回转换后的内容
}
// 使用
string str = convert<string>(921);
int num = convert<int>("122");
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][
我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])
我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.
我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e
这是针对我无法破坏的现有公共(public)API,但我确实希望对其进行扩展。目前,该方法采用字符串或符号或任何其他在作为第一个参数传递给send时有意义的内容我想添加发送字符串、符号等列表的功能。我可以只使用is_a吗?数组,但还有其他发送列表的方法,这不是很像ruby。我将调用列表中的map,所以第一个倾向是使用respond_to?:map。但是字符串也会响应:map,所以这行不通。 最佳答案 如何将它们全部视为数组?String的行为与仅包含String的Array相同:deffoo(obj,arg)[*arg].eac
考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://
我有一个像这样的ruby类:require'logger'classTdefdo_somethinglog=Logger.new(STDERR)log.info("Hereisaninfomessage")endend测试脚本行如下:#!/usr/bin/envrubygem"minitest"require'minitest/autorun'require_relative't'classTestMailProcessorClasses当我运行这个测试时,out和err都是空字符串。我看到消息打印在stderr上(在终端上)。有没有办法让Logger和capture_io一起玩得
在运行Cucumber测试时,我得到(除了测试结果)大量调试/日志相关的输出形式:D,[2013-03-06T12:21:38.911829#49031]DEBUG--:SOAPrequest:D,[2013-03-06T12:21:38.911919#49031]DEBUG--:Pragma:no-cache,SOAPAction:"",Content-Type:text/xml;charset=UTF-8,Content-Length:1592W,[2013-03-06T12:21:38.912360#49031]WARN--:HTTPIexecutesHTTPPOSTusingt