-----------------------------------------------------------------------------------------------------------------------------
数值程序中使用C++流实现程序之间的数据传送
本文转自 http://blog.csdn.net/pandaxcl/article/details/655180
#if 0 在编写数值计算程序的过程中,经常需要大量的数值输入,通常来说是:一个程序用 于产生数据,另一个程序用来接收产生的数据作为输入。通常的做法是采用文件操作,但 是在我编写数值计算的过程中发现:C++中还可以用更加简单直接的方式实现这种数据传送 的目的。这种方法就是直接使用C++流库具备的输入输出能力,使得编码过程尽可能的简单 ,这样就可以更加专注于算法的实现。 好了,说了这么多,我们来看看在实际的编写过程中该如何实现。 #endif #ifdef SOURCE //产生数据的源程序 //该程序仅仅只是输出两个数组的数据到标准输出流中 #include <iostream> #include <iterator> int main() { double A[10]={1,2,3,4,5,6,7,8,9,0}; double B[10]={0,9,8,7,6,5,4,3,2,1}; std::copy(A,A+10,std::ostream_iterator<double>(std::cout,"/n")); std::cout << "*" << std::endl;//必须用一个分隔符来分隔多个数据 std::copy(B,B+10,std::ostream_iterator<double>(std::cout,"/n")); return 0; } #endif//SOURCE #ifdef TARGET //接收数据的目标程序 //该程序仅仅只是从标准输入流中接收两个数组的数据到程序中的数组中。为了对比分别 //将两个数组的在从流中读取数据的前后向标准日志流中分别输出了两个数组中的数据。 #include <iostream> #include <iterator> int main() { double A[10]={0}; double B[10]={0}; //下面的代码和数据传送无关,仅仅输出初始的数据以给出初始数组值 std::copy(A,A+10,std::ostream_iterator<double>(std::clog," ")); std::clog << std::endl; std::copy(B,B+10,std::ostream_iterator<double>(std::clog," ")); std::clog << std::endl; //在下面这行代码从流中读取数据到A数组的时候,读到'*'时,流状态错误,停止读取 std::copy(std::istream_iterator<double>(std::cin),std::istream_iterator<double>(),A); std::cin.clear(); //在这里恢复流状态为正常状态 std::cin.ignore(10,'*');//并且忽略掉至多10个字符,当遇到'*'的时候忽略慈字符之后停止忽略过程 //从当前的流中继续读取剩余的数据到B数组中 std::copy(std::istream_iterator<double>(std::cin),std::istream_iterator<double>(),B); //下面的代码和数据传送无关,仅仅输出读入的数据以检查数据传送是否成功 std::copy(A,A+10,std::ostream_iterator<double>(std::clog," ")); std::clog << std::endl; std::copy(B,B+10,std::ostream_iterator<double>(std::clog," ")); return 0; } #endif//TARGET //以上代码的编译方法: //g++ -DSOURCE file.cpp -o source //g++ -DTARGET file.cpp -o target //上面命令中的file.cpp指的使本文档 //这两个程序的运行方法如下: //source|target //这种运行方式的输出结果为: /******************************************************************************* 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 0 9 8 7 6 5 4 3 2 1 *******************************************************************************/ //另外还可以分成两部分单独计算,这样可以节省运算时间。运行方式如下: //source > source.txt //target < source.txt >target.txt #if 0 从上面的示例代码中可以看出:我直接使用了C++库存的流对象std::cout和std::cin 来完成数据传送任务,而程序运行中的提示信息通过std::clog的方式输出。这样就可以让 std::cout和std::cin专门负责数据传送同时也可以输出提示信息。职责分明,代码得到了 充分的简化。只有这样才可以使人们更加专注于编写小巧的程序,而不是大而全的程序, 读代码就像读文档一样,可以大大提高编码的效率和成功率。对于数值计算程序来说,将 程序的功能分成各个小的程序还有助于减少重复计算,加快运行速度。好了,说了这么多 在这里只是抛砖引玉,您的发挥将会给出更多更有用的方式:)
--------------------------------------------------------------------------------------------------------------------------------
ostringstream函数的使用
转自http://blog.csdn.net/jiahehao/archive/2008/04/04/2250642.aspx
当存在未知数据大小的时候,可以使用 ostringstream 来代替 sprintf , 避免总是申请大量的缓冲区.用法可以参照下面转载的文章.
另外解决今天遇到的一个问题,如果要重复使用一个ostringstream对象,并且需要在下次使用前清空缓冲区,则可以使用str()函数重设置缓冲区. 如:
ostringstream osSql;
//first time
osSql<<"SELECT COUNT(*) FROM t_XXXX";
...
clsConnection.Query( osSql );
....
//second time
osSql.str("");//重新使用一个空的缓冲区
osSql<<"INSERT INTO **********"<< strBigText ;
.......
以下转载 一篇关于 ostringstream 的用法 的文章
在写程序的时候,我们往往需要对字符串进行格式化, 比如写SQL语句的时候. 在ANSI C 中可以sprintf(), 在MFC中可以用CString::Format()对字符串进行格式化. 但前者无法实现字符串的动态增加,比如你定义的字符缓存为100个字节,如果你格式化以后的内容超出了100个字节,那边后面的内容就无法看见. 所以一般来讲都为定义一个足够的字符缓冲,但这样的效率是很差的. 后者虽然可以解决这个问题,但有一点, 他和前者一样,存在着安全隐患. 比如下面的代码:
char buf[100]={0};
const char* str = "string";
sprintf(buf,"this is a string : %s , %s", str);
或者
CString s;
s.Format("this is a string: %s, %s",str);
前面那个%s对应第一个参数str,那么第二个%s呢, 指针指向何方? 如果你幸运的话,什么事也不会发生或者你仅仅获得一个你觉得莫名奇妙的字符串值. 但更严重的情况呢, 不用说----访问越界!你的程序就等着迎接臭名远扬的Windows红框吧!
如果你使用STL的sstream,那么一切将归于寂然:
#include<sstream>
...
ostringstream str;
str<<"this is a str" << "string"<<"and this is a interger<<3<<endl;
你不必考虑字符串的增长问题, 也不用在写程序时去一一匹配你的format函数的format参数是否一一匹配(如果你的参数很多,那么这项检查工作将是一个让你头痛万分的工作).
一切都是如此的简单.
如果你想获取格式化好的字符串, 通过ostringstream::str()函数就可以返回一个string对象, 调用string::c_str() 或string::data()函数就可以获得一个指向字符缓冲的char*变量.
另外, 我坚决建议用string替代CString . 因为CString在设计时考虑到效率问题, 内存是重复利用的, 即:一个进程中所有的CString对象都使用同一个内存缓冲区,且这个内存区运行时不会释放,直到进程结束为止. 如果缓冲不够,他会无限制往上增长. 如果你设计的系统是一个7*24运行的系统且字符串分析工作量很大,程序中产生了大量的CString对象的话, 你可能会发现你的内存会不断的上涨. string同样有一个很优秀且高效率的内存管理机制,但他不会死守着你的内存不放,这一点你看看STL的源码就知道了.
如果你觉定采用STL,那么建议你使用VC7.0作为开发环境或者GCC , 因为这两款开发工具对STL支持是还算不错.尤其是GCC. 如果你坚持用VC6的话,那么你最好打上SP5补丁包, VC6对STL的支持不够理想.