Solved

Convert a char to upper case

Posted on 1998-11-01
16
1,015 Views
Last Modified: 2013-11-20
What is the best way to make a char variable upper case? It's not that hard when I have a string (MakeUpper() is built in to CString). But it's different with just a char.

I tried
   CString(charCurrent).MakeUpper()
And got the error
   error C2120: 'void' illegal with all types

I could convert the char to a CString temporarily, convert its case, and change it back to a char. But that is inefficient, involves too many steps, and uses a temporary variable.

I can't use _strupr because it expects char *:
   error C2664: '_strupr' : cannot convert parameter 1 from 'char' to 'char *' (new behavior; please see help)

How about CharUpper(charCurrent)? The documentation says lpsz can be "single character or pointer to string". But it doesn't seem to work with my single character:
   error C2664: 'CharUpperA' : cannot convert parameter 1 from 'char' to 'char *' (new behavior; please see help)
It's like it expects a string (char *). Am I doing some thing wrong?

(Visual C++ 4.0)
0
Comment
Question by:TylerRick
  • 7
  • 4
  • 2
  • +2
16 Comments
 

Expert Comment

by:f4817
ID: 1324124
Hello,
Just do that
if(myChar > 90) // myChar > 'Z' ?
   myChar -= 32;
0
 

Author Comment

by:TylerRick
ID: 1324125
That would work. But I'd like something that I could use inline in an expression.

For example, I want to do this:
if (charCurrent == CharUpper(charCurrent))
to check if it is upper case. (I know I could just check if it is > 'z', but there are other times when I really need to convert a char.)

I suppose
if (charCurrent == charCurrent < 'A' ? charCurrent + 32 : charCurrent)
might work. But what if it isn't a letter? Then it wouldn't work to add 32 to the value.

0
 

Expert Comment

by:f4817
ID: 1324126
BOOL IsCharUpper(char cVar)
{
if (cVar <= 'Z' && cVar >= 'A')
   return TRUE;
return FALSE;
}

void UpperChar(char & cVar)
{
cVar -= 32;
}

void LowerChar(char & cVar)
{
cVar += 32;
}

0
 
LVL 3

Expert Comment

by:stefanr
ID: 1324127
There are some WIN32 functions that will do this for you:

LPTSTR CharUpper(
   LPTSTR lpsz   // single character or pointer to string
);

LPTSTR CharLower(
   LPTSTR lpsz   // single character or pointer to string
);

Parameters
lpsz
Pointer to a null-terminated string or specifies a single character. If the high-order word of this parameter is zero, the low-order word must contain a single character to be converted.

Return Values
If the operand is a character string, the function returns a pointer to the converted string. Since the string is converted in place, the return value is equal to lpsz.

If the operand is a single character, the return value is a 32-bit value whose high-order word is zero, and low-order word contains the converted character.

There is no indication of success or failure. Failure is rare. There is no extended error information for this function; do not call GetLastError.

Remarks
Windows NT: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using the Control Panel. If no language has been selected, Windows completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using the Control Panel. Windows 95 does not have language drivers.

QuickInfo
  Windows NT: Requires version 3.1 or later.
  Windows: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h.
  Import Library: Use user32.lib.
  Unicode: Implemented as Unicode and ANSI versions on Windows NT.

I have used it like this:

void CPositionEditEx::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
   nChar = UINT(::CharUpper(LPTSTR(nChar))); // UNICODE and character set compliant.

[snip]

Hope this helps.
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1324128
toupper in the C runtime library too (ctypes.h header)

char c = toupper( 'x' ) ;  // c will now contain 'X'

C++ runtime includes a library too
0
 
LVL 3

Expert Comment

by:stefanr
ID: 1324129
toupper will certainly work, as long you're not using Unicode.
I would however recommend _totupper, which is a macro that evolves to toupper in ANSI, and towupper in Unicode (and to _mbctoupper in when _MBCS is defined).
0
 

Author Comment

by:TylerRick
ID: 1324130
I tried
 if (charCurrent == CharUpper(LPTSTR(charCurrent))
and got
 error C2446: '==' : no conversion from 'char *' to 'int' (new behavior; please see help)

What does LPTSTR(nChar) do? Is it meant to convert nChar to LPTSTR? And what is LPTSTR? That's char*, right?

Also, _toupper sounds like a good function that I wasn't aware of, but it won't work here because it converts the character...
 if (charCurrent == _toupper(charCurrent))

0
 
LVL 3

Expert Comment

by:stefanr
ID: 1324131
if (charCurrent == TCHAR(CharUpper(LPTSTR(charCurrent))

or

if (int(charCurrent) == _totupper(charCurrent))

should do it.

LPTSTR is TCHAR*, which is char* in ANSI and wchar_t* in Unicode.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 3

Expert Comment

by:stefanr
ID: 1324132
By the way, LPTSTR(nChar) does a type conversion, just like the old C style (LPTSTR) nChar, or the more complex static_cast<LPTSTR>(nChar).
0
 
LVL 12

Expert Comment

by:migel
ID: 1324133
Problem is that you give value, not pointer! But You can`t pass pointer to the single character due to ALL string functions require ASCIIZ strings (finished by zero)

You can make temporary array of chars and path it to the functions:

TCHAR arrTemp[2] = {chChar, '\0'};
::AnsiUpper(arrTemp);
chChar = arrTemp[0];
0
 
LVL 3

Expert Comment

by:stefanr
ID: 1324134
For WIN32, AnsiUpper is obsolete. It is for compatibility reasons implemented as a macro that calls CharUpper. And it is no need to create a temporary array of chars, since the function itself understands that a char type-casted to char* is a char and not a zero terminated string.
0
 
LVL 12

Expert Comment

by:migel
ID: 1324135
Ok, please reject my ansver.
0
 

Author Comment

by:TylerRick
ID: 1324136
Yay, that works:

if (charCurrent == TCHAR(CharUpper(LPTSTR(charCurrent)))

This probably shows my ignorance of MFC, but why do we use all those typedef'd names, like TCHAR and LPTSTR? Wouldn't it be easier to understand to just say

if (charCurrent == (char)CharUpper((char*)charCurrent)

? Is it to make cross-platform applications easier? (I'm just targeting Windows 95...)
0
 
LVL 3

Expert Comment

by:stefanr
ID: 1324137
If you are using only Windows 95, you would most certainly do that way. I'm, however, uses Windows NT with a risk of being needed to port a lot of code to Windows CE sometime in the future. Since NT uses both ANSI and Unicode, and CE uses _only_ Unicode I go the safe way of using the typedefs and macros to ease the pain in converting code between the two character sets. It's a good habit anyway, because you never know what you are supposed to do in the future. And Unicode is faster to use under Windows NT since it uses that internally anyway. Using ANSI requires an extra step of the called ANSI functions to convert to Unicode and back again, and that costs some performance.
0
 

Author Comment

by:TylerRick
ID: 1324138
Thank you all very much for your help. I think I understand it now. Would some one like to take the credit for the answer, stefanr?
0
 
LVL 3

Accepted Solution

by:
stefanr earned 50 total points
ID: 1324139
OK! Thank you, TylerRick.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video discusses moving either the default database or any database to a new volume.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now