折腾了一晚C++

太久没用C++了(离上次打开VC6.0相隔差不多正好一年),昨天花了一个晚上写了个小程
序。故事的起因和Lisa与我合作的那篇准备参加明年PAA年会的paper有关。
话说8月底我刚回来时,和Lisa一起去见美丽的导师Susan,向她请教我们在为这篇paper做
data management中遇到的问题。Susan指点一二后,让我们自行解决。之后的3周,我和
Lisa着实花了些功夫torture data,写申请参加PAA年会的abstract。搞定这事后,学期渐入‘
佳境’,我们各自顾着忙各自的,下一步的data management几乎停滞。
这两天我略有空闲,独自摆弄起这份data来,结果一发不可收拾。这份data来自入户survey
,data中的每个observation是个individual;原始data中记录了每个individual的household id
(相当于一个数字编码的户名),每个household的id是unique的;同时原始data中记录了
每个individual在其household中的line number(相当于每个人在家庭中的一个数字编码),
这个line number用以区别同一个household中的不同member。换言之,如果把household id
和line number结合起来创建一个新的变量(姑且命名为ID),这个新变量就可以单独区别出
每个不同的observation了。在把两个data file(比如一个data file包含着每个人的收入情况,
另一个包含着每个人的教育水平)合并成一个data file时(比如Stata中的merge操作),必
须要有这样一个可以uniquely identify observations的ID变量。
以前我创建的这个新的ID变量一直工作得好好的,但这两天当我合并两个或更多个data file
时,它就抽风了。每次合并时,Stata都报告这个ID变量无法uniquely identify observations。
我被气糊涂了,今天下午找了一个有2000多个observations的data file,试图人工挨个检查
到底哪些observations的ID是相同/重复的。
当然,我很快放弃了这项苦力活,晚上回家整起C++了。其实方法也挺笨拙的:先把Stata
格式的data file中的ID变量那列导出到一个txt文件中,再用一个C++程序把这个txt文件中的
ID数据读入到一个数组/向量中,然后遍历这个数组/向量,检查是否有相同的ID值;如果有
,就report这个ID值以及其在数组中的位置。
有两点问题需要特别指出。我希望这是个通用程序,也就是说它能读取人为指定的保存在
硬盘上任何位置的任何txt文件,同时这个txt文件中能包含任意个observations。所以首先,
要解决读取txt文件路径及位置的问题;其次不能使用数组(因为数组的长度必须在创建改数
组时申明,但现在的问题是我们不知道某个txt文件中会有多少个observations,也就是说在
读取文件之前不知道该设定多大的数组),所以必须用C++的容器类,比如vector。
简言之,我昨晚花了4个小时,温习/学习了C++的两个知识点:文件的I/O操作与容器类
vector的使用。经测试,该程序运行正常,且符合要求,希望明天拿去系里操作时别出新茬
子。
最后感谢Stanley Lippman写了C++ Primer这本殿堂级的书(我今晚发现国内网站上的很多
文章、帖子直接‘摘录’了Lippman书中的例子,但并未注明出处),尽管地球人都知道这本
书挂羊头卖狗肉,讲述的东西远超出primer这个词的定义,也许这也是这本书的中文版之所
以名为“C++Primer中文版”而非“C++入门”或"C++初级读物"的原因吧。
附源代码:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void main()
{
 
 cout<<"Please enter the file name: ";
 string file_name;
 cin>>file_name;
 ifstream infile(file_name.c_str());
 if(!infile)
 {
  cerr<<"error: unable to open input file: "
        <<infile<<endl;
 }
 vector <double> ID;
 double input;
 while(infile>>input)
 {
  ID.push_back(input);
 }
 for(int i=0;i<ID.size();++i)
 {
  for(int j=i+1;j<ID.size();++j)
  {
   if (ID[i]==ID[j]) cout<<"Observation "
                                 <<i+1<<", whose value="<<ID[i]
                                 <<", is not unique"<<endl;
  }
 }
 system("pause");
}

About Hongwei Xu

I'm a social demographer, a single-child, a husband, and a father.
This entry was posted in 未分类. Bookmark the permalink.

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s