Thursday, July 24, 2014

Some utility c++ functions

Might be useful later:

//
//  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 ) {
        std::cerr << "File does not exist!" << "\n";
        throw "File does not exist!";
    }
}

// count lines of a file
uint countlines(std::string fn) {
    std::ifstream in_file(fn);
    uint nlines =  (uint) std::count(std::istreambuf_iterator<char>(in_file), std::istreambuf_iterator<char>(), '\n');

    // nlines needs be corrected when the last line is not ended with a newline
    in_file.seekg(-1, in_file.end);
    unsigned char lastchar = in_file.get();
    if(lastchar != '\n') {
        ++nlines;
    }

    return nlines;
}

// print each line of a file
void printlines(std::string fn) {
    std::ifstream in_file(fn);
    std::string tmpline;
    while(in_file) {
        std::getline(in_file, tmpline);
        std::cout << tmpline << "\n";
    }
}

// get the last line of a file
std::string lastline(std::string fn) {
    fileExists(fn);
    std::ifstream in_file(fn);
    std::string tmpline;
    unsigned char tmpchar;
    in_file.seekg(-1, in_file.end);
    tmpchar = in_file.get();

    // if the last char is a newline, ignore it
    if(tmpchar == '\n') {
        in_file.seekg(-2, in_file.end);
    } else {
        in_file.seekg(-1, in_file.end);
    }

    // trace back the file until a newline is read
    tmpchar = in_file.get();
    while(in_file) {
        if(tmpchar != '\n') {
            in_file.seekg(-2, in_file.cur);
            tmpchar = in_file.get();
        } else {
            break;
        }
    }

    // read the last line
    std::getline(in_file, tmpline);
    std::cout << "Last line: " << tmpline << "\n";
    return tmpline;
}

// check if a file has trailing whitespaces
bool checktrail(std::string fn) {
    std::string llast = lastline(fn);
    boost::algorithm::trim(llast);
    bool checktrail_res = llast == "" ? true : false;
    if (checktrail_res) {
        std::cout << "It has trailing whitespaces!" << "\n";
    } else {
        std::cout << "OK, no trailong whitespaces." << "\n";
    }
    return checktrail_res;
}


size_t bimNCols(std::string 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();
}



// remove elements from a std::vector, conditionally
void testerase() {
    std::vector<std::string> svec {"", "", "hi", "there", ""};
    svec.erase(std::remove_if(svec.begin(), svec.end(), [](std::string const& s) {return s=="";}));
    for(int i=0; i<svec.size(); i++) {
        std::cout << svec[i] << "\n";
    }
}


int main(int argc, const char * argv[])
{
    // insert code here...
    std::string tmpfn = "/Users/kaiyin/Desktop/testfile";
    uint n = countlines(tmpfn);
    std::cout << "File lines: " << n << "\n";
    checktrail(tmpfn);
    std::cout << "It has " << bimNCols(tmpfn) << " columns" << "\n";
    testerase();

    return 0;
}

0 comments: