Hi all,

The code below is to converts a tchar from lowercase to uppercase.
Could you tell me if my code is correct or need to be fixed.
Thank you very much.
VM
===============================

tchar* MyToUpper(tchar *input) {     
  static tchar buffer[1000];       
  tchar *s= input;                
  tchar *t= buffer;               
                                  
  while (*s!= '\0') {             
    *t= *s+ 'A' - 'a';           
    s+;                           
    t+;                           
  }                                
  return buffer;                   
}

There is no such data type as "tchar". Do you mean TCHAR that is defined in tchar.h? If that is right, then TCHAR is defined as either char* or wchar_t*, depending on if the program is compiled for UNICODE or not.

And to answer your question, no that function will not work. What happens if the string contains characters other than 'a'-'z'? What you need to use is toupper() defined in ctype.,h

There is no such data type as "tchar". Do you mean TCHAR that is defined in tchar.h? If that is right, then TCHAR is defined as either char* or wchar_t*, depending on if the program is compiled for UNICODE or not.

And to answer your question, no that function will not work. What happens if the string contains characters other than 'a'-'z'? What you need to use is toupper() defined in ctype.,h

=================================

Hi Ancient Dragon,

Thank you for your response.
How about I change as below,
Will it work?
Thanks so much for your help.
==============================

TCHAR*  MyToUpper(TCHAR *input) {     
  static TCHAR buffer[1000];       
  TCHAR *s = input;                
  TCHAR *t= buffer;               
                                   
  while (*s != '\0') {             
    *t = toupper(*s);           
    s++;
    t++;                           
  }                                
  return buffer;                   
}

use _totupper(), which is portable between char* and wchar_t* Also, you need to null-terminate the string after that loop terminates.

This function won't work correctly when you convert multiple strings to their uppercase equivalents.
Yes, you return a pointer, but to something in static memory.
When you for example let your function uppercase "hello", your function will return a pointer to "HELLO", okay you save the memory address, then you call the function with another string, this time: "world", now your function will overwrite the previous existing value by "WORLD", and then return a pointer to it, but the first pointer now also points to the same memory, so we have two pointers pointing to the string "WORLD" now.

Hi Acient Dragon,

I've just modified. Will this work?

Thanks very much,
VM
=============================

TCHAR*  MyToUpper(TCHAR *input) {     
  static TCHAR buffer[1000];       
  TCHAR *s = input;                
  TCHAR *t= buffer;               
                                   
  while (*s != '\0') {             
    *t = _toupper(*s);           
    s++;
    t++;                           
  }     

  *t ='\0';
  return buffer;                   
}

>> *t = _toupper(*s);
You still didn't use the right function. Read my previous post

tux4life: That's a common problem with several standard C library functions, such as strtok() and localtime(). A better design is to have the calling function pass in a buffer for the destination string.

>That's a common problem with several standard C library functions
Yes, maybe, but I don't see any good reason on why to write a program which contains this common problem again.
(unless it's an assignment and his instructor explicitly asks him to do so).

Hi tux4life,

Thank you for your reply.
To avoid that problem should I remove 'static'
or other way to handle such situation, could you
please suggest?

Thank you very much for your help,
VM

Thank you for your reply.
To avoid that problem should I remove 'static'
or other way to handle such situation, could you
please suggest?

Ancient Dragon has already pointed out a possible solution for this problem:

A better design is to have the calling function pass in a buffer for the destination string.

I already did suggest another solution -- and No you can not just simply remove the static keyword.

TCHAR*  MyToUpper(TCHAR *input, TCHAR* buffer) {     
  TCHAR *s = input;                
  TCHAR *t= buffer;               
                                   
  while (*s != '\0') {             
    *t = _totoupper(*s);           
    s++;
    t++;                           
  }     

  *t ='\0';
  return buffer;                   
}

AD: *t = _totoupper(*s); I don't know that function, please tell me about it :P

commented: LOL :) +36

AD: *t = _totoupper(*s); I don't know that function, please tell me about it :P

See the link in my post #4

commented: Yes, but they don't mention _totOupper, only: _totupper :P +15

Hi Acient Dragon,

Thank you for shedding the light on my code.
I'm courious that if I remove 'static' and use local
pointer as below, what are the potential problems?
Will that cause memory overflow?

TCHAR*  MyToUpper(TCHAR *input) {     
  TCHAR  buffer[1000];       
  TCHAR *s = input;                
  TCHAR *t= buffer;               
                                   
  while (*s != '\0') {             
              *t = _toupper(*s);           
    	s++;
    	t++;                           
  }     

  *t ='\0';  	                           
  return buffer;                   
}

The problem is that variable buffer disappears as soon as that function goes out of scope (returns) and the return value is an invalid pointer. Can't do that.

Hi tux4life,

Thank you for your helping on correcting the code.
VM

Hi AD,

The function returns the buffer in its body, so it's still in the scope
and its value still available, isn't it?

Thanks,
VM

Hi AD,

The function returns the buffer in its body, so it's still in the scope
and its value still available, isn't it?

Thanks,
VM

In Ancient Dragon's code it's correct because in his code a pointer to a function argument is returned which means that the memory for that argument was allocated outside that function.
So when the function returns, the memory is still intact for the buffer because you defined the buffer somewhere outside the function's body.
As a result, you can access the upper-cased string directly by using the name of the variable you used as buffer in you program, or via the pointer the function returns to buffer.

In general you should remember the following: your function may return a pointer to a variable which it has received as an argument, but when you want your function return a pointer to a variable which was defined in the function's body itself, you should use dynamic memory allocation to ensure the memory still exists, when the function has returned.
(= to ensure the pointer is pointing to valid memory, valid memory which still belongs to your program)

If you wouldn't do it, the function would return a pointer to for example a local variable which' memory is de-allocated when the function returns.
In fact you can do this (returning a pointer to a local variable defined inside the function's body), but it can be dangerous, because the pointer your function returns is now pointing to a piece of memory which doesn't belong to the program anymore.

AD: *t = _totoupper(*s); I don't know that function, please tell me about it :P

See the link in my post #4

Ohhhh I get it now :) :) Sometimes I'm a little slow at reading sarcastic remarks

If the project is built by undefining UNICODE and _UNICODE macros, TCHAR in your routine defaults to ASCII 1 Byte char * string. But, if you force UNICODE input string to your routine, your routine will only parses the first byte and immediately returns with out parsing/converting the entire input string.

Example:

If the call is as follows:

TCHAR *input = (TCHAR *) L"sudar";
Toupper(input);
commented: Way too late to be of any use to this dead thread -4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.