Welcome
Welcome to the forums of AntiRTFM's Absolute N00b Spoonfeed C++ Tutorials!

You are currently viewing our boards as a guest, which gives you limited access to view most discussions and access our other features. By joining our free community, you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content, and access many other special features. Registration is fast, simple, and absolutely free, so please, <a href="/profile.php?mode=register">join our community today</a>!

String case conversion

Display your little helpful snippets of code that may help us all get something done

String case conversion

Postby C++ on Fri Sep 05, 2008 10:20 am

I made these functions because the string class doesn't provide these and the standard functions only convert a single char. I thought they might be helpful since they prevent the extra function call that's needed when using tolower/toupper from cctype.

Code: Select all
void toUpper(string &str)
{
   for (unsigned int i = 0; str[i] != '\0'; ++i)
   {
     if (str[i] > 0x60 && str[i] < 0x7b)
          str[i] &= 0xdf;
   }
}

void toLower(string &str)
{
   for (unsigned int i = 0; str[i] != '\0'; ++i)
   {
     if (str[i] > 0x40 && str[i] < 0x5b)
          str[i] |= 0x20;
   }
}



Using by reference is the preferred way, but you can use pointers to if you have to.

Code: Select all
void toUpper(string *str)
{
   for (unsigned int i = 0; str->operator[](i) != '\0'; ++i)
   {
     if (str->operator[](i) > 0x60 && str->operator[](i) < 0x7b)
          str->operator[](i) &= 0xdf;
   }
}

void toLower(string *str)
{
   for (unsigned int i = 0; str->operator[](i) != '\0'; ++i)
   {
     if (str->operator[](i) > 0x40 && str->operator[](i) < 0x5b)
          str->operator[](i) |= 0x20;
   }
}
New to C++ programming? Click here
C++
teh awesome
 
Posts: 217
Joined: Sun May 25, 2008 7:45 am

Re: String case conversion

Postby antiRTFM on Fri Sep 05, 2008 1:20 pm

Cool.

Another way of doing
Code: Select all
str->operator[](i)
is
Code: Select all
(*str)[i]


Looks like your technique depends entirely on the layout of the ASCII code page. Some may argue that that is not the best way of doing it, but instead one should use more platform specific APIs to do things like this.
User avatar
antiRTFM
Administrator
 
Posts: 462
Joined: Sun Apr 13, 2008 9:10 am

Re: String case conversion

Postby C++ on Sat Sep 06, 2008 7:07 pm

That's true :)
I decided they might be useful because most people use either Windows or Linux anyway. I just wanted to have a fast way of doing the conversion without extra function calling. To make things even easier I made a custom String class to implement the case methods. It also provides string array indexing with bounds checking. It's derived from the std::string class so it also has all basic string operations. Since std:string is not a polymorphic class you can't use polymorphic features for the custom String class, since that can lead to undefined behavior. With polymorphic I mean you can't use a base class pointer to reference the String object. Doing so can result in strange things happening when the wrong destructor gets called. You don't need polymorphic features anyway for this to be useful.

To use it all you have to do is include String.h in your program. :D

Code: Select all
// String.h

#pragma once

#include <string>
#include "Bounds.h"


class String : public std::string
{
    size_t length;
public:
    String(const std::string &);
    String(const char *);
    String();
    ~String();
    String & operator=(const std::string &);
    String & operator=(const char *);
    const char & operator[](const size_t) throw(Bounds);
    const String & operator>>(std::string &);
    void toUpper();
    void toLower();
};


Code: Select all
// String.cpp

#include "String.h"

using std::string;


String::String(const string &str) : string(str), length(size())
{
}

String::String(const char *str) : string(str), length(size())
{
}

String::String() : length(0)
{
}

String::~String()
{
}

String & String::operator=(const string &str)
{
    assign(str);
    length = size();
    return *this;
}

String & String::operator=(const char *str)
{
    assign(str);
    length = size();
    return *this;
}

const char & String::operator[](const size_t index) throw(Bounds)
{
    if (index >= length)
        throw Bounds("Out of bounds error.");
    return *(data() + index);
}

const String & String::operator>>(string &str)
{
    str.assign(data());
    return *this;
}

void String::toUpper()
{
    for (unsigned int i = 0; i < length; ++i)
    {
        if (at(i) > 0x60 && at(i) < 0x7b)
            at(i) &= 0xdf;
    }
}

void String::toLower()
{
    for (unsigned int i = 0; i < length; ++i)
    {
        if (at(i) > 0x40 && at(i) < 0x5b)
            at(i) |= 0x20;
    }
}


Code: Select all
// Bounds.h

#pragma once

#include <exception>


class String;

class Bounds : public std::exception
{
    String *const str;
    virtual const char * what() const throw();
public:
    Bounds(const char *);
    Bounds(const String &);
    Bounds();
    virtual ~Bounds() throw();
};


Code: Select all
// Bounds.cpp

#include "Bounds.h"
#include "String.h"


const char * Bounds::what() const throw()
{
    return str->data();
}

Bounds::Bounds(const char *_str) : str(new String(_str))
{
}

Bounds::Bounds(const String &_str) : str(new String(_str))
{
}

Bounds::~Bounds() throw()
{
    delete str;
}
New to C++ programming? Click here
C++
teh awesome
 
Posts: 217
Joined: Sun May 25, 2008 7:45 am

Re: String case conversion

Postby antiRTFM on Sat Sep 06, 2008 9:16 pm

careful not to cause header-file name ambiguities, as a "string.h" file does exist amongst the standard C headers.
User avatar
antiRTFM
Administrator
 
Posts: 462
Joined: Sun Apr 13, 2008 9:10 am

Re: String case conversion

Postby C++ on Mon Sep 08, 2008 6:09 am

antiRTFM wrote:careful not to cause header-file name ambiguities, as a "string.h" file does exist amongst the standard C headers.


Frankly, I don't see how that could be a problem. If you include it with the "" then the compiler will look for the header file in the current directory. It would be a problem if you include it using <> as well, or put the custom header in the include path of the compiler. Linux does not have these issues to begin with, since file names are case sensitive.
New to C++ programming? Click here
C++
teh awesome
 
Posts: 217
Joined: Sun May 25, 2008 7:45 am

Re: String case conversion

Postby asib on Mon Sep 08, 2008 12:41 pm

Boy do I hate operator overlods O_O. Aswell as pointers. I understand them and how they work, but using them can sometimes get deep and confusing.
asib
 
Posts: 86
Joined: Tue Jul 22, 2008 9:15 pm

Re: String case conversion

Postby Vevix on Sat Oct 10, 2009 9:32 pm

Why aren't you using the STL?

Example:

Code: Select all
#include <algorithm>
#include <string>

std::string Test("Hello World");
std::transform(Test.begin(), Test.end(), Test.begin(), tolower);


The above converts the string to lowercase, Simple replace tolower with toupper for uppercase
User avatar
Vevix
 
Posts: 75
Joined: Sat Oct 10, 2009 9:24 pm
Location: ntdll.dll


Return to Snippets

Who is online

Users browsing this forum: No registered users and 0 guests