Showing posts with label cplusplus. Show all posts
Showing posts with label cplusplus. Show all posts

Sunday, August 31, 2014

How To: Missing String Related Functions in C++ - Replace, Split, Trim etc.

String manipulation functions are really important and we often find ourselves needing them while coding in C++. High-level languages like C# and Java etc. provide such functions through methods of a string class. However, they are not inherently present in C++.

Here are some of the more frequently used string related functions. They are pretty self-explanatory. All of them are independent functions. Hope you find them useful.

Note: Don't forget to include the appropriate headers: <string> <vector> <sstream>

using namespace std;

string strToLowerCase(string str) {

    const int length = str.length();
    for(int i=0; i < length; ++i) {
        str[i] = tolower(str[i]);
    }
    return str;
}

string strToUpperCase(string str) {

    const int length = str.length();
    for(int i=0; i < length; ++i) {
        str[i] = toupper(str[i]);
    }
    return str;
}

void strReplace(string &str, const string what, const string to) {

    if (str.empty() || what.empty()) return;

    size_t pos;
    while ( (pos = str.find(what)) != string::npos ) {
        str.replace(pos, what.length(), to);
    }
}

vector<string> strSplit(string s, char delim) {
    vector<string> elems;
    stringstream ss(s);
    string item;
    while(getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

string strTrim(string str) {

    size_t pos1 = str.find_first_not_of(" \t");
    size_t pos2 = str.find_last_not_of(" \t");

    str = str.substr(pos1 == string::npos ? 0 : pos1,
        pos2 == string::npos ? 0 : pos2 - pos1 + 1);

    return str;
}

bool strStartsWith(string str, string start) {

    if (start.length() > str.length()) return false;
    if ( str.substr(0, start.length()) == start ) return true;
    else return false;
}

bool strEndsWith(string str, string end) {

    if (end.length() > str.length()) return false;
    if ( str.substr(str.length() - end.length()) == end ) return true;
    else return false;
}

int strCountWords(string str) {

    int count = 0;
    for (int i=0; i < str.length(); i++) {
        if (isspace(str.at(i))) count++;
    }
    return (count+1);
}


Thursday, August 28, 2014

C++ - Take Screenshot of the Windows Desktop using GDI+

Here is the complete C++ source code for taking screenshot in Windows:

#include <iostream>
#include <string>
#include <windows.h>
#include <gdiplus.h>

#pragma comment(lib, "gdiplus.lib")

using namespace std;
using namespace Gdiplus;

int GetEncoderClsid(WCHAR *format, CLSID *pClsid)
{
    unsigned int num = 0,  size = 0;
    GetImageEncodersSize(&num, &size);
    if(size == 0) return -1;
    ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
    if(pImageCodecInfo == NULL) return -1;
    GetImageEncoders(num, size, pImageCodecInfo);
 
    for (unsigned int j = 0; j < num; ++j) {
        if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0) {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;
        }  
    }
    free(pImageCodecInfo);
    return -1;
}

int SaveScreenshot(string filename, ULONG uQuality) // by Napalm
{
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    HWND hMyWnd = GetDesktopWindow();
    RECT r;
    int w, h;
    HDC dc, hdcCapture;
    int nBPP, nCapture, iRes;
    LPBYTE lpCapture;
    CLSID imageCLSID;
    Bitmap *pScreenShot;
 
    // get the area of my application's window    
    GetWindowRect(hMyWnd, &r);
    dc = GetWindowDC(hMyWnd);   // GetDC(hMyWnd) ;
    w = r.right - r.left;
    h = r.bottom - r.top;
    nBPP = GetDeviceCaps(dc, BITSPIXEL);
    hdcCapture = CreateCompatibleDC(dc);

    // create the buffer for the screenshot
    BITMAPINFO bmiCapture = { sizeof(BITMAPINFOHEADER), w, -h, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0, };

    // create a container and take the screenshot
    HBITMAP hbmCapture = CreateDIBSection(dc, &bmiCapture, DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0);

    // failed to take it
    if (!hbmCapture) {
        DeleteDC(hdcCapture);
        DeleteDC(dc);
        GdiplusShutdown(gdiplusToken);
        printf("failed to take the screenshot. err: %d\n", GetLastError());
        return 0;
    }

    // copy the screenshot buffer
    nCapture = SaveDC(hdcCapture);
    SelectObject(hdcCapture, hbmCapture);
    BitBlt(hdcCapture, 0, 0, w, h, dc, 0, 0, SRCCOPY);
    RestoreDC(hdcCapture, nCapture);
    DeleteDC(hdcCapture);
    DeleteDC(dc);

    // save the buffer to a file  
    pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
    EncoderParameters encoderParams;
    encoderParams.Count = 1;
    encoderParams.Parameter[0].NumberOfValues = 1;
    encoderParams.Parameter[0].Guid  = EncoderQuality;
    encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
    encoderParams.Parameter[0].Value = &uQuality;
    GetEncoderClsid(L"image/jpeg", &imageCLSID);

    wchar_t *lpszFilename = new wchar_t[filename.length() + 1];
    mbstowcs( lpszFilename, filename.c_str(), filename.length() + 1);
 
    iRes = (pScreenShot->Save(lpszFilename, &imageCLSID, &encoderParams) == Ok);
    delete pScreenShot;
    DeleteObject(hbmCapture);
    GdiplusShutdown(gdiplusToken);
    return iRes;
}

// Example program code:

int main() {
    string path = "screenshot.jpg";
    ULONG quality = 100;
    SaveScreenshot(path, quality);
 
    return 0;
}


If you have any problem running this code, please comment below. I will be glad to help you out.

Tags: screenshot in C++, screenshot using gdiplus, gdiplus library

C++ - Get File Size in KB/MB/GB Format using stat()

This code uses stat() function of the built-in sys/stat.h header file, to get the size of a file.

The size is then passed to convertSize function which converts the file size to a suitable unit and returns the result as a string value.

You might want to know that stat(), however, isn't part of the C++ standard, so it may or may not be available in your compiler.

These utility functions are really useful and might come in handy for you in solving other problems as well.

#include <iostream>
#include <string>
#include <sstream>
#include <windows.h>
#include <sys/stat.h> /* for stat() function */

using namespace std;

// Utility functions:


string convertToString(double num) {
    ostringstream convert;
    convert << num;
    return convert.str();
}

double roundOff(double n) {
    double d = n * 100.0;
    int i = d + 0.5;
    d = (float)i / 100.0;
    return d;
}

string convertSize(size_t size) {              
    static const char *SIZES[] = { "B", "KB", "MB", "GB" };
    int div = 0;
    size_t rem = 0;

    while (size >= 1024 && div < (sizeof SIZES / sizeof *SIZES)) {
        rem = (size % 1024);
        div++;
        size /= 1024;
    }

    double size_d = (float)size + (float)rem / 1024.0;
    string result = convertToString(roundOff(size_d)) + " " + SIZES[div];
    return result;
}

int file_size(const char *path) {
    struct stat results;

    if (stat(path, &results) == 0) {
        return results.st_size;
    } else {
        return -1;
    }
}

// This is the function that you will call:
string getFileSize(string path) {
    size_t size = file_size((const char *)path.c_str());
    return convertSize(size);
}


// Example program:
int main() {
    cout << getFileSize("D:\\httrack_x64-3.48.13.exe") << endl;
    return 0;
}


This code has been test with Visual Studio 2008 and Dev-C++. If you have any problems running this code, please comment below. I will be glad to help you out.

Tags: C++, convert size, file size in c++, round off, size in string, length of file in c++