Tag Archives: Strings

How to replace all occurrences of a character in a std::string

This can be done using the standard library or Boost. The advantage of using Boost is that you get Boost ranges, which mean that you don’t need to specify the beginning and end of the string.

With both libraries, the replacement can be made on the original string or a copy.

  1. Use std::replace()
  2. Use std::replace_copy
  3. Use boost_replace_all
  4. Use boost_replace_all_copy

Method 1: Use std::replace()

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::string str("Quick+brown+fox");
    std::replace(str.begin(), str.end(), '+', ' ');
    std::cout << str << "\n";
}

Method 2: Use std::replace_copy

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::string str1("Quick+brown+fox");
    std::string str2(str1.size(), '\0');
    std::replace_copy(str1.begin(), str1.end(), str2.begin(), '+', ' ');
    std::cout << str2 << "\n";
}

Method 3: Use boost_replace_all

#include <iostream>
#include <string>
#include <boost/algorithm/string/replace.hpp>

int main()
{
    std::string str("Quick+brown+fox");
    boost::replace_all(str, "+", " ");
    std::cout << str << "\n";
}

Method 4: Use boost_replace_all_copy

#include <iostream>
#include <string>
#include <boost/algorithm/string/replace.hpp>

int main()
{
    std::string str1("Quick+brown+fox");
    std::string str2 =  boost::replace_all_copy(str1, "+", " ");
    std::cout << str2 << "\n";
}

References:
Function template replace_all
Function replace_all_copy

Related

Reverse a string in Python

To reverse a string, make a slice with a negative step value:

print "abcd"[::-1]

You might be tempted to use reversed(), but this returns an iterator, so you need to join() it to make a string again:

print "".join(reversed("abcd"))

How to read a file into a string in C++

Method

  1. Open the file
  2. Seek to the end and use tell to find out how big it is
  3. Seek back to the beginning
  4. Construct a string with the length + 1 and fill it with nul characters so it’s nul-terminated
  5. Read the contents into the string’s buffer

You can do this using iostreams or stdio.

Using iostreams

    std::ifstream in(filename);
    if (in) {
        in.seekg(0, std::ios::end);
        size_t len = in.tellg();
        in.seekg(0);
        std::string contents(len + 1, '\0');
        in.read(&contents[0], len);
    }

Using stdio

    std::FILE* fptr = std::fopen(filename.c_str(), "r");
    if (fptr) {
        std::fseek(fptr, 0, SEEK_END);
        size_t len = std::ftell(fptr);
        std::fseek(fptr, 0, SEEK_SET);
        std::string contents(len + 1, '\0');
        std::fread(&contents[0], 1, len, fptr);
        fclose(fptr);
    }

Related

How to list the Files in a Directory in C++

How to do case-insensitive string comparison in C++

Methods

  1. Use std::equal and std::toupper
  2. Use boost::iequals

1. Use std::equal and std::toupper

#include <string>
#include <algorithm>
#include <cstring>

struct iequal
{
    bool operator()(int c1, int c2) const
    {
        return std::toupper(c1) == std::toupper(c2);
    }
};

bool iequals(const std::string& str1, const std::string& str2)
{
    return std::equal(str1.begin(), str1.end(), str2.begin(), iequal());
}

2. Use boost::iequals

#include <boost/algorithm/string/predicate.hpp>

bool same = boost::iequals(str1, str2);

Reference: Function template iequals

Related

How to concatenate a string and an int in C++

Methods

  • Use std::stringstream
  • Use boost::lexical_cast()
  • Use boost::format()
  • Use std::to_string() (C++11)

Method 1. Use std::stringstream

#include <sstream>

std::stringstream ss;
ss << name << age;
result = ss.str();

Method 2. Use boost::lexical_cast()

#include <boost/lexical_cast.hpp>

result = name + boost::lexical_cast<std::string>(age);

Reference: Boost.Lexical_Cast

Method 3. Use boost::format()

#include <boost/format.hpp>

result =  boost::str(boost::format("%s%d") % name % age);

Reference: Boost Format library

Method 4. Use std::to_string() (C++11)

result = name + std::to_string(age);

Method 5. Use folly::toAppend()

#include <folly/Conv.h>

result =  name;
folly::toAppend(age, &result);

Reference: folly/Conv.h

Related

How to convert a string to lower or upper case in C++

1. Use std::transform and tolower or toupper

    #include <algorithm>
    #include <string>
    #include <cctype> 

    std::string& to_lower(std::string& str)
    {
        std::transform(str.begin(), str.end(), str.begin(), static_cast<int(*)(int)>(std::tolower));
        return str;
    }

    std::string& to_upper(std::string& str)
    {
        std::transform(str.begin(), str.end(), str.begin(), static_cast<int(*)(int)>(std::toupper));
        return str;
    }

    std::string str = "Chorlton-cum-Hardy"; 
    to_lower(str);
    to_upper(str);

2. Use boost::algorithm::to_lower or boost::algorithm::to_upper

    #include <boost/algorithm/string.hpp>    

    std::string str = "Adwick-le-Street";
    boost::algorithm::to_lower(str);
    boost::algorithm::to_upper(str);

References:
Function template to_lower
Function template to_upper

Related

How to trim a std::string in C++

There is no standard way of trimming a string, but it’s possible to implement using the methods in the string class:

  • Left trim: Use find_first_not_of() to find the characters to erase
  • Right trim: Use find_first_of() to find the characters to erase
  • Trim: Do a right trim followed by a left trim (or vice-versa)

Use erase() to actually erase the characters.

Here is my implementation. It defaults to trimming whitespace characters but you can specify any string of characters as the second argument.

std::string& ltrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    str.erase(0, str.find_first_not_of(chars));
    return str;
}

std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    str.erase(str.find_last_not_of(chars) + 1);
    return str;
}

std::string& trim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
{
    return ltrim(rtrim(str, chars), chars);
}

Here’s a test program:

int main()
{
    std::string strings[] = {"", " ", "test", " test", "test ", " test "};
    const size_t n = sizeof(strings) / sizeof(std::string);
    for (unsigned int i = 0; i < n; ++i) {
        std::string str = strings[i];
        trim(str);
        std::cout << "\"" << str << "\"" << "\n";
    }
}

And here’s the valgrind output:

==23049== Memcheck, a memory error detector
==23049== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==23049== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==23049== Command: ./trim
==23049==
""
""
"test"
"test"
"test"
"test"
==23049==
==23049== HEAP SUMMARY:
==23049==     in use at exit: 0 bytes in 0 blocks
==23049==   total heap usage: 16 allocs, 16 frees, 475 bytes allocated
==23049==
==23049== All heap blocks were freed -- no leaks are possible
==23049==
==23049== For counts of detected and suppressed errors, rerun with: -v
==23049== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Related