-4

main.cpp

#include <iostream>
#include "Module2.h"

int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;

}

Module2.h

#include <iostream>
#include "Module2.h"

int main()
{
std::cout<<"This is a test of Module2.h"<<std::endl;
std::cout<<UCase("This is a test of UCase")<<std::endl;
std::cout<<LCase("This is a test of LCase")<<std::endl;
system("pause");
return 0;

}

Module2.cpp

///////////////////////////////////////////////////
//Module : Module2.cpp
//
//Purpose : Shows the usage of modular functions
///////////////////////////////////////////////////

#include "Module2.h"

///////////////////////////////////////////////////
//UCase()

char *UCase(char *str)
{
//convert each char in  the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
    std::cout<<"In UCase"<<std::endl;
     str[i]=toupper(str[i]);
}

return str;
}

///////////////////////////////////////////////////
//LCase()

char *LCase(char *str)
{
//convert each char in  the string to uppercase
//
int len = strlen(str);
for ( int i ; i < len ; i++)
{
    std::cout<<"In LCase"<<std::endl;
    str[i]=tolower(str[i]);
}  
return str;
}

When I run it there is no warning or error . But , it don't upper and lower the string . I have thought my for loops are wrong , but it seems to be right . What's wrong with my code.

goInDoor
  • 1
  • 3

3 Answers3

2

The main problem is that you are trying to modify string literals such as "This is a test of UCase". This is undefined behaviour. You need to copy the literals into a char array that you can modify.

Also note that binding char* to a string literal is deprecated and forbidden, for good reason. This should have emitted a warning:

UCase("This is a test of UCase") // not good: binding char* to literal

There are other problems with your code: undefined behaviour (UB) in loops with uninitialized variables,

for ( int i ; i < len ; i++) // using uninitialized i: UB

You should also have a look at toupper and tolower documentation. They both accept int with some restrictions on their values. You have to ensure you don't pass a value that causes undefined behaviour, bearing in mind that char can be signed. See for example Do I need to cast to unsigned char before calling toupper?

Community
  • 1
  • 1
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
1

Loops like this one have undefined behavior:

for ( int i ; i < len ; i++)

The reason is that you did not start i at value 0.
You have no idea what value i starts at!
It could be -10, could be 824.

If you want a value to be initialized, you have to initialize it.
I suggest:

for (int i=0; i < len; i++)
abelenky
  • 63,815
  • 23
  • 109
  • 159
0
char *UCase( char *str)
{
char ch;
int i=0;

while(str[i])
{
    ch=str[i];
    putchar(toupper(ch));
//putchar : The value is internally converted to an unsigned char when written.
    i++;
}
}

///////////////////////////////////////////////////
//LCase()

char *LCase(char *str)
{
char ch;
int i=0;

while(str[i])
{
    ch=str[i];
    putchar(tolower(ch));
    i++;
}
}

I finally write this . Although , I still not quite understand , but I learned

#include <ctype.h>
int tolower( int ch );

means tolower toupper can change only one character each time , so I can not

tolower ("This is a test of LCase");

code like this .

goInDoor
  • 1
  • 3