473,396 Members | 1,987 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

toUpper and pointer to a string

my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {
int i;

strcpy (*myStr);

for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
}
}

help?

:)

Sep 22 '07 #1
16 8130
In article <11**********************@k79g2000hse.googlegroups .com>,
ba***************@gmail.com says...
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {
It's probably not related to the problem you're seeing, but this name
(and any other starting with 'str') is reserved for use by the
implementation.
int i;

strcpy (*myStr);
This is probably your biggest problem. If you're going to call strcpy,
you need to supply two arguments. Fortunately, you don't seem to need to
use strcpy at all, so you can just delete this entirely.
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
This will usually work, but can give undefined behavior. You normally
want something like:
myStr[i] = toupper((unsigned char)myStr[i]);

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 22 '07 #2
On Sep 22, 11:59 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <1190478693.852512.115...@k79g2000hse.googlegroups .com>,
baronessfrostb...@gmail.com says...
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);

This will usually work, but can give undefined behavior. You normally
want something like:
myStr[i] = toupper((unsigned char)myStr[i]);
I don't really understand this statement. toupper() is a function
taking an int parameter. How would a cast change anything, much less
one to unsigned char?

Sep 22 '07 #3
gaga schrieb:
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {
int i;

strcpy (*myStr);

for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
}
}

help?
Hello,

this is the way I would write this function:

void strUpper(char *str)
{
while (*str) {
*str = toupper(*(str++));
}
}

Cya,
Daniel Kay
Sep 22 '07 #4
On Sep 22, 9:31 pm, gaga <baronessfrostb...@gmail.comwrote:
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {
int i;

strcpy (*myStr);
char myCopy[100]; //sufficiently large
strcpy(myCopy, myStr);
>
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
myCopy[i] = toupper(myStr[i]);
}

}

help?
Few other points to note
1. If you are not changing the myStr argument, change the prototype to
void strUpper (const char *myStr)
2. Better, use std::string class and std::transform. Something like
this:

void strUpper (string s)
{
string t;
transform(s.begin(), s.end(), back_inserter(t), (int(*)
(int))toupper);
}
-N

Sep 22 '07 #5
Neelesh Bodas schrieb:
On Sep 22, 9:31 pm, gaga <baronessfrostb...@gmail.comwrote:
>my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {
int i;

strcpy (*myStr);

char myCopy[100]; //sufficiently large
strcpy(myCopy, myStr);
Always a bad idea...
>
> for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);

myCopy[i] = toupper(myStr[i]);
> }

}

help?

Few other points to note
1. If you are not changing the myStr argument, change the prototype to
void strUpper (const char *myStr)
2. Better, use std::string class and std::transform. Something like
this:

void strUpper (string s)
{
string t;
transform(s.begin(), s.end(), back_inserter(t), (int(*)
(int))toupper);
}
This function will not change anything, unless the function retrieves a
pointer or even better a reference to a std::string.

--
Cya,
Daniel

Sep 22 '07 #6
On Sep 22, 10:45 pm, Daniel Kay <daniel-k...@arcor.dewrote:
Neelesh Bodas schrieb:
On Sep 22, 9:31 pm, gaga <baronessfrostb...@gmail.comwrote:
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.
void strUpper (char *myStr) {
int i;
strcpy (*myStr);
char myCopy[100]; //sufficiently large
strcpy(myCopy, myStr);

Always a bad idea...
Completely Agreed. but I think there is always a need of writing this
kind of code. For example, the strUpper you suggested (or the OP tried
to write) cannot be used in the following case:

int main()
{
strToUpper("helloworld");
}

Worse, there is nothing that stops you from writing such a code (The
non-const nature of parameter doesn't hints at it though). In such a
case, probably creating a local variable to copy the argument is the
only option.
2. Better, use std::string class and std::transform. Something like
this:
void strUpper (string s)
{
string t;
transform(s.begin(), s.end(), back_inserter(t), (int(*)
(int))toupper);
}

This function will not change anything, unless the function retrieves a
pointer or even better a reference to a std::string.
Ok, one can have
string strUpper (const string& s); //returns the local variable t by
value
or
void strUpper(string& s); //no need of local variable, transform the
argument

The central idea was to suggest that std::string is much safer to use
than char*.
-Neelesh

Sep 22 '07 #7
On Sep 22, 10:58 pm, Neelesh Bodas <neelesh.bo...@gmail.comwrote:
Worse, there is nothing that stops you from writing such a code (The
non-const nature of parameter doesn't hints at it though).
typo. meant "does hint at it though"

-N

Sep 22 '07 #8
Neelesh Bodas schrieb:
On Sep 22, 10:45 pm, Daniel Kay <daniel-k...@arcor.dewrote:
>Neelesh Bodas schrieb:
>>On Sep 22, 9:31 pm, gaga <baronessfrostb...@gmail.comwrote:
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.
void strUpper (char *myStr) {
int i;
strcpy (*myStr);
char myCopy[100]; //sufficiently large
strcpy(myCopy, myStr);
Always a bad idea...

Completely Agreed. but I think there is always a need of writing this
kind of code. For example, the strUpper you suggested (or the OP tried
to write) cannot be used in the following case:

int main()
{
strToUpper("helloworld");
}

Worse, there is nothing that stops you from writing such a code (The
non-const nature of parameter doesn't hints at it though). In such a
case, probably creating a local variable to copy the argument is the
only option.
If somebody would force me to write a function in C (what I try to avoid
in any way), which will not modify the input string, I would start with
the following declaration:

void strToUpper(const char* in, char* out);

The user can decide to modify the original string:

char str1[] = "hello";
strToUpper(str1, str1);
Or the user can copy the result into a new string:

char str1[] = "hello";
char str2[sizeof(str1)] = { 0 };
strToUpper(str1, str2);

I hope this is true, since I didn't compile it... :-)
>>2. Better, use std::string class and std::transform. Something like
this:
void strUpper (string s)
{
string t;
transform(s.begin(), s.end(), back_inserter(t), (int(*)
(int))toupper);
}
This function will not change anything, unless the function retrieves a
pointer or even better a reference to a std::string.

Ok, one can have
string strUpper (const string& s); //returns the local variable t by
value
or
void strUpper(string& s); //no need of local variable, transform the
argument

The central idea was to suggest that std::string is much safer to use
than char*.
Ok, just wanted to make sure that uses copy/paste with that function and
wonders why the string isn't changed like the original poster intended
to do.

--
Cya,
Daniel
Sep 22 '07 #9
Neelesh Bodas schrieb:
On Sep 22, 10:58 pm, Neelesh Bodas <neelesh.bo...@gmail.comwrote:
>Worse, there is nothing that stops you from writing such a code (The
non-const nature of parameter doesn't hints at it though).

typo. meant "does hint at it though"
Still you can't call a function which declares a char* argument with a
const char* value. The only way to do this is by using evil casts. But
in that case it's the callers fault if bad things happen.

--
Cya,
Daniel
Sep 22 '07 #10
In article <11**********************@50g2000hsm.googlegroups. com>,
Ju*****************@gmail.com says...
On Sep 22, 11:59 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <1190478693.852512.115...@k79g2000hse.googlegroups .com>,
baronessfrostb...@gmail.com says...
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
This will usually work, but can give undefined behavior. You normally
want something like:
myStr[i] = toupper((unsigned char)myStr[i]);

I don't really understand this statement. toupper() is a function
taking an int parameter. How would a cast change anything, much less
one to unsigned char?
The standardese for it is: "In all cases, the argument is an int, the
value of which shall be representable as an unsigned char or shall equal
the value of the macro EOF. If the argument has any other value, the
behavior is undefined." (That exact wording is from $7.4/1 of the C99
standard, but it's essentially the same for C and C++ overall).

To explain that in a bit more detail, in a typical case, char is signed,
and some characters (especially those used in non-English alphabets) are
represented as negative numbers. Casting to unsigned char converts those
to positive numbers and this positive number is subsequently converted
to int, normally maintaining its value.

Perhaps a concrete example would help. In a typical case, char has a
range of -128..127. Casting to unsigned char gives a number in the range
0-255. Anything that started out in the range 0-127 remains unchanged,
while anything that was in the range -128..-1 maps to the range 128-255.
This value is then converted to an int -- but since int must accomodate
positive values of at least 32767, all values remain unchanged.

Most of the isXXX and toXXX functions are typically table-driven. This
means the value they receive is used as an index into an array. For
example, toupper might look like:

int toupper(int ch) {
return __upper_case[ch+1];
}

where __upper_case looks something like:

int __upper_case[UCHAR_MAX+1];

and somewhere in the startup code, it's initialized something like this:

for (int i=0; i<UCHAR_MAX+1; ++i)
__upper_case[i] = i-1;
for (int i=0; i<26; i++)
__upper_case['a'+i+1] = 'A'+i;
// ...

Of course, this code is non-portable -- it's basically for ASCII in the
"C" locale. For other locales and/or character sets (EBCDIC, ISO/8859/x,
etc.) the initialization would be different. The exact values aren't
terribly important at the moment though -- what's important is that the
value you pass is being used (almost) unchanged as an index into an
array, and the only negative number that's accomodated is -1 (which is
the typical encoding for EOF). If you pass other negative numbers, it
attempts to index before the beginning of the array, which gives
undefined behavior. As noted above, implementing toupper and tolower in
this fashion still conforms entirely with the requirements of the
standard.

People often wonder why tolower and toupper don't do this cast
themselves -- in a typical case (i.e. a twos-complement machine) the
cast just reinterprets the same bit pattern, so it carries no run-time
performane penalty. The answer is simple: these functions ARE required
to accomodate EOF, and if they cast EOF to an unsigned char, they'd
(typically) produce incorrect results. If they added in a test for EOF
before doing the cast, that would add overhead.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 22 '07 #11
On Sep 22, 1:41 pm, Jerry Coffin <jcof...@taeus.comwrote:
In article <1190481919.236035.321...@50g2000hsm.googlegroups. com>,
Justin.SpahrSumm...@gmail.com says...
On Sep 22, 11:59 am, Jerry Coffin <jcof...@taeus.comwrote:
In article <1190478693.852512.115...@k79g2000hse.googlegroups .com>,
baronessfrostb...@gmail.com says...
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
This will usually work, but can give undefined behavior. You normally
want something like:
myStr[i] = toupper((unsigned char)myStr[i]);
I don't really understand this statement. toupper() is a function
taking an int parameter. How would a cast change anything, much less
one to unsigned char?

The standardese for it is: "In all cases, the argument is an int, the
value of which shall be representable as an unsigned char or shall equal
the value of the macro EOF. If the argument has any other value, the
behavior is undefined." (That exact wording is from $7.4/1 of the C99
standard, but it's essentially the same for C and C++ overall).

To explain that in a bit more detail, in a typical case, char is signed,
and some characters (especially those used in non-English alphabets) are
represented as negative numbers. Casting to unsigned char converts those
to positive numbers and this positive number is subsequently converted
to int, normally maintaining its value.

Perhaps a concrete example would help. In a typical case, char has a
range of -128..127. Casting to unsigned char gives a number in the range
0-255. Anything that started out in the range 0-127 remains unchanged,
while anything that was in the range -128..-1 maps to the range 128-255.
This value is then converted to an int -- but since int must accomodate
positive values of at least 32767, all values remain unchanged.
You're right (obviously). I knew about each individual item you
mentioned, but I just didn't connect it to the bigger picture like
you've done in that explanation, so thanks for that.

Sep 22 '07 #12
On Sat, 22 Sep 2007 10:59:49 -0600, Jerry Coffin <jc*****@taeus.com>
wrote in comp.lang.c++:
In article <11**********************@k79g2000hse.googlegroups .com>,
ba***************@gmail.com says...
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.

void strUpper (char *myStr) {

It's probably not related to the problem you're seeing, but this name
(and any other starting with 'str') is reserved for use by the
implementation.
Actually, this usage is ok. Identifiers beginning with "is", "to",
"str", and "mem" followed by a lower case letter are reserved.
Following "str" with 'U' does not violate the implementation
namespace.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Sep 22 '07 #13
In article <fb********************************@4ax.com>,
ja*******@spamcop.net says...

[ ... ]
Actually, this usage is ok. Identifiers beginning with "is", "to",
"str", and "mem" followed by a lower case letter are reserved.
Following "str" with 'U' does not violate the implementation
namespace.
Oops -- quite right. My apologies for the misinformation, and thanks for
the correction.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 22 '07 #14
On Sep 22, 7:30 pm, Daniel Kay <daniel-k...@arcor.dewrote:
gaga schrieb:
my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.
void strUpper (char *myStr) {
int i;
strcpy (*myStr);
for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
}
}
this is the way I would write this function:
void strUpper(char *str)
{
while (*str) {
*str = toupper(*(str++));
}
}
Well, I'd certainly use something different, based on
std::string, keeping the original value somewhere, and in no
case converting in place. (Toupper is not a one-to-one
relationship; converting a single lower case character will
sometimes result in a string of more than one character.) But
if you insist on in place and one to one, then
std::ctype<>::toupper already does the job, without the undefined
behavior above:

void strUpper( char* str, std::locale const& loc = std::locale() )
{
std::use_facet< std::ctype< char ( loc )
.toupper( str, str + strlen( str ) ) ;
}

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 23 '07 #15
On Sep 22, 7:42 pm, Neelesh Bodas <neelesh.bo...@gmail.comwrote:
2. Better, use std::string class and std::transform. Something like
this:
void strUpper (string s)
{
string t;
transform(s.begin(), s.end(), back_inserter(t), (int(*)
(int))toupper);
}
Which will result in undefined behavior. The function you want
is std::ctype< char >::toupper(). But as a member function,
you'll need some fancy binders (or boost::bind) to make it work.
The case occurs often enough in my code to have justified
writing my own special binders, so I can write things like:

std::string
strUpper( std::string const& s )
{
std::string result ;
std::transform( s.begin(), s.end(),
std::back_inserter( result ),
CTypeToUpper() ) ;
return result ;
}

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 23 '07 #16
James Kanze schrieb:
On Sep 22, 7:30 pm, Daniel Kay <daniel-k...@arcor.dewrote:
>gaga schrieb:
>>my function should accept a pointer to a string as its argument. and
it should convert each charater to an uppercase letter. I know what i
need to do, its just my syntax is all out of whack.
>>void strUpper (char *myStr) {
int i;
>> strcpy (*myStr);
>> for(i=0; myStr[i]; i++) {
myStr[i] = toupper(myStr[i]);
}
}
>this is the way I would write this function:
>void strUpper(char *str)
{
while (*str) {
*str = toupper(*(str++));
}
}

Well, I'd certainly use something different, based on
std::string, keeping the original value somewhere, and in no
case converting in place. (Toupper is not a one-to-one
relationship; converting a single lower case character will
sometimes result in a string of more than one character.) But
if you insist on in place and one to one, then
std::ctype<>::toupper already does the job, without the undefined
behavior above:

void strUpper( char* str, std::locale const& loc = std::locale() )
{
std::use_facet< std::ctype< char ( loc )
.toupper( str, str + strlen( str ) ) ;
}
Off cource std::string is better. But what you have wrote looks
interesting. I'll have a look at it...

--
Cya,
Daniel
Sep 23 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Claudia Fong | last post by:
Hi, I'm trying to convert a string into a Upper case; in the book said that I need to use ToUpper(the string that I want to convert to upper case) but it happens that C# "generate" the error...
5
by: shan_rish | last post by:
Hi Group, When i compile the following program it compiles successfully, but crashes while executing. I am trying to assign a NULL char pointer to a string. The error message is ...
15
by: roberts.noah | last post by:
Are there any decent benchmarks of the difference between using c strings and std::string out there? Google isn't being friendly about it. Obviously this would be dependant on different...
4
by: sandy | last post by:
I am trying to upper case a string, so I have this method: string FileSystem::toupper(string S) { for (int i=0; i<S.length(); ++i) { S=toupper(S); } return S;
2
by: shinjianata | last post by:
I have been asked to make a program which can change lowercase letter to upper case without using any given functions from C libraries ( for example toupper from string.h ). It should work like this...
14
by: fniles | last post by:
In VB.NET 2005 can I check if a letter in a string is upper case or lower case ? For example: I have the following 2 lines: NQ,Z2003,11/11/2003,1416.5,1420,1402,1411.5...
7
eboyjr14
by: eboyjr14 | last post by:
I am very new to C++. I am just learning and wanted to make a simple program that capitalizes the input. What is wrong with this? I use Bloodshed Dev-C++. I get this error: no matching function...
4
by: thyagi | last post by:
a function which takes a string (pointer to char) as a parameter and returns the integer equivalent.str2int("1658") would return the value 1658 To improve your program change the function to accept...
4
by: prasad8619 | last post by:
please help me out in this regard as this is urgent to me because i stuck in the middle of a program....... here I have a program like this...... char name="rajesh"; char...
6
by: abhinuke | last post by:
I am trying to print prime numbers from 1 to 100. I am passing an array to a function and then zeroing all the elements which are multiples of 2,3,5. When I compile the code,I am getting all the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.