Click here to Skip to main content
Click here to Skip to main content
Alternative Tip/Trick

Tagged as

How to Toggle String Case in .NET

, 17 Feb 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Couldn't resist: The following is a rewrite of Alternative 9, ToggleCaseHA()This is an unmanaged version which does direct manipulation of the input stringunsafe static string ToggleCaseUnmanaged(string str){ fixed(char* p = str) { for(int i=str.Length-1;i!=-1;--i)...
Couldn't resist: The following is a rewrite of Alternative 9, ToggleCaseHA()
 
This is an unmanaged version which does direct manipulation of the input string
 
unsafe static string ToggleCaseUnmanaged(string str)
{
    fixed(char* p = str)
    {
        for(int i=str.Length-1;i!=-1;--i)
        {
            char ch = p[i];
            char foo = (char)(ch & ~0x20);
            if((foo >= 0x41 && foo <= 0x5a) || (foo >= 0xc0 && foo<=0xde && foo != 0xd7))
            {
                p[i] = (char)(ch ^ 0x20);
            }
            else if((foo == 0xdf || ch>0xff) && char.IsLetter(ch))
            {
                p[i] = char.IsLower(ch) ? char.ToUpper(ch) : ch;
            }
        }
    }
 
    return str;
}
 
WARNING: This version will change the SOURCE string instead of creating a copy.
 
Using test phrase 4 available on http://webinfocentral.com/resources/toggleCaseAlgorithm.aspx[^] with 100.000 iterations:
 
ToggleCaseHA: 165,4507 milliseconds
ToggleCaseByCeChode: 117,3497 milliseconds
ToggleCaseUnmanaged: 67,367 milliseconds
 
----------------------------------------
Dear Michael,
 
Thanks for sharing this code snippet. There is minor bug in the code: when working w/Unicode string it does not toggle Lower to Upper (fixed in the following version, see Listing 1.).
 
Also, there is no need for return string as you already passed it as parameter ByRef and your code modifies it in that way that return value is the same as the value of the string passed as parameter. In production version the function could be void, but in this test version I've used return value for the duration in us.
 
In terms of performance: when tested on a standard ASCII your version appeared to be a speed champion in our "League of Best Toggle Case Algorithms" Smile | :) , but tested on Unicode string it demonstrated performance similar to the algorithm submitted by Henry Ayoola (you could refer to the test page and try the Unicode Test Phrase 2, for example, or enter your own).
 
Have a great day.
Kind regards,
Alex Bell
 
Listing 1. Class Library
//**************************************************************************************
// Module           :   ToggleCase.cs
// Description      :   Fast Algorithm to toggle the string case: Upper/Lower
// Note:            :   Using Unsafe code (C#)
//**************************************************************************************
// Developed by     :   Michael B. Hansen, Denmark
// Modified by      :   Alexander Bell, USA
// Date             :   Feb 17 2011
//**************************************************************************************
//// Reference
// http://www.codeproject.com/Tips/158876/How-to-Toggle-String-Case-in-NET.aspx
//// Test site
// http://localhost:11334/WebInfoCentral/RESOURCES/ToggleCaseAlgorithm.aspx
//**************************************************************************************
using System;
 
namespace ToggleStringCase 
{
    public static class ToggleCase
    {
        /// <summary>
        /// Toggle Case Algorithm using unsafe code (C#)
        /// Performance benchmark
        /// </summary>
        /// <param name="str">string</param>
        /// <returns>string: duration, us</returns>
        unsafe public static string ToggleCaseUnmanagedByMBH(string str)
        {
 
            DateTime dt = DateTime.Now;
            // using 100001 iterations
            for (int j = 0; j < 100001; j++)
            {
                fixed (char* p = str)
                {
                    for (int i = str.Length - 1; i != -1; --i)
                    {
                        char ch = p[i];
                        char foo = (char)(ch & ~0x20);
                        if ((foo >= 0x41 && foo <= 0x5a) || 
                            (foo >= 0xc0 && foo <= 0xde && foo != 0xd7))
                        {
                            p[i] = (char)(ch ^ 0x20);
                        }
                        else if ((foo == 0xdf || ch > 0xff) && char.IsLetter(ch))
                        {
                            // MOD Alex Bell
                            //p[i] = char.IsLower(ch) ? char.ToUpper(ch) : ch;
                            p[i] = char.IsLower(ch) ? char.ToUpper(ch) : char.ToLower(ch);
                        }
                    }
                }
            }
 
            // function return duration in us (microseconds)
            TimeSpan ts = DateTime.Now - dt;
            double dur = (double)ts.Milliseconds / 100;
            
            // MOD Alex Bell
            //return str;
            return dur.ToString() + " us";
        }
    }
}
//**************************************************************************************

Listing 2: Calling Function (Button Click event)

protected void Button7_Click(object sender, EventArgs e)
{
    string s = txtBox.Text;
    Label7.Text = ToggleCase.ToggleCaseUnmanagedByMBH(s);
    txtBox.Text = s;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael B. Hansen
Systems Engineer SPAMfighter
Denmark Denmark
I have a MCPD .NET 3.5 EAD and a Bsc in computer science, organizational theory and economics, and work as lead developer on SPAMfighter Exchange Module and SPAMfighter Mail Gateway in SPAMfighter, Europe's leading Anti Spam Filter developer.

Comments and Discussions

 
GeneralAS FYI: It seems like the site does not allow to run unsafe ... PinmemberDrABELL17-Feb-11 17:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 17 Feb 2011
Article Copyright 2011 by Michael B. Hansen
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid