Thursday, July 24, 2014

Read a column of a bim file into an std::vector in c++

Here is the code:

//
//  main.cpp
//  cppfuncsXcode
//
//  Created by Kaiyin Zhong on 23/07/14.
//  Copyright (c) 2014 com.mycomp. All rights reserved.
//

#include <iostream>
#include <cstdlib>
#include <vector>
#include <cctype>
#include <algorithm>
#include <fstream>
#include <boost/algorithm/string.hpp>
#include <sstream>




typedef unsigned int  uint;


inline void fileExists (const std::string& name) {
    if ( access( name.c_str(), F_OK ) == -1 ) {
        throw std::string("File does not exist!");
    }
}

size_t bimNCols(std::string fn) {
    try {
        fileExists(fn);
        std::ifstream in_file(fn);
        std::string tmpline;
        std::getline(in_file, tmpline);
        std::vector<std::string> strs;
        strs = boost::split(strs, tmpline, boost::is_any_of("\t"), boost::token_compress_on);
        return strs.size();
    } catch (const std::string& e) {
        std::cerr << "\n" << e << "\n";
        exit(EXIT_FAILURE);
    }
}

typedef std::vector<std::string> vecStr;

vecStr bimReadCol(std::string fn, uint ncol_select) {
    try {
        size_t ncols = bimNCols(fn);
        if(ncol_select < 1 or ncol_select > ncols) {
            throw std::string("Your column selection is out of range!");
        }

        std::ifstream in_file(fn);
        vecStr colsel; // holds the column of strings
        std::string tmpword;
        while (in_file) {
            tmpword = "";
            for(int i=1; i<=ncol_select; i++) {
                in_file >> tmpword;
            }
            if(tmpword != "") {
                colsel.push_back(tmpword);
            }
            in_file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        return colsel;

    } catch (const std::string& e) {
        std::cerr << "\n" << e << "\n";
        exit(EXIT_FAILURE);
    }
}





int main(int argc, const char * argv[])
{
    // insert code here...
    std::string tmpfn = "/Users/kaiyin/Desktop/testplink/test2.bim";
    std::cout << "It has " << bimNCols(tmpfn) << " columns" << "\n";
    vecStr col = bimReadCol(tmpfn, 1);
    std::cout << "col has " << col.size() << " elements\n";
    for(std::string i : col) {
        std::cout << i << "\n";
    }
    return 0;
}

Also see this post on stackoverflow: c++ – How to eliminate this extra element? – Stack Overflow

0 comments: