Good Morning,

I'm a little difficulty in writing and implementing a function that read a list of words of variable lengths and convert all letters to upper case. Ask the user to enter the size of the list. I shall use an array as pointers.

So far, I have this, but it's not working. Can anyone help me out.

char toUpper(char * chPtrs[5], char tmpStr[1000], char word)                            
{
    for (int j=0; j<5; j++)
    {
        cout<<"enter a word => ";                     
        cin>>tmpStr;                                    

        chPtrs[j] = new char[strlen(tmpStr)];           
        strcpy(chPtrs[j], tmpStr);  

        static char lower[] = tmpStr;
        for (int i = 0; lower[i] != '0'; i++)
        {
            if (word >= 'a' && word <= 'Z')
                cout << "The word converted to upper case is:"<< static_cast<char> ( word + 'A' - 'a') <<endl;
        }

    }

Dani AI

Generated

A concise diagnosis and two safe fixes (C-style and modern C++) that address the bugs visible in the thread.

The original implementation had three common mistakes that explain the symptoms seen in the outputs: using tmpStr after the input loop (so only the last word gets converted), allocating new char[strlen(tmpStr)] without the extra byte for the terminating '\0', and iterating with the wrong length/indices (for example strlen(*chPtrs) or printing each string by indexing into every pointer in a single loop) which leads to out-of-bounds access and garbage. As pointed out, the allocation needs room for the null terminator. was also correct to point toward the cctype helpers, and ’s high-level idea of converting characters as they are read is fine if applied to whole strings rather than a single char.

Corrected C-style approach (keeps array-of-pointers):

#include <iostream>
#include <cstring>
#include <cctype>

void upperCase(char* list[], int n) {
    char buffer[1000];
    for (int i = 0; i < n; ++i) {
        std::cin >> buffer;
        std::size_t len = std::strlen(buffer);
        list[i] = new char[len + 1];                 // +1 for '\0'
        std::strcpy(list[i], buffer);
        for (std::size_t j = 0; j < len; ++j)
            list[i][j] = static_cast<char>(
                std::toupper(static_cast<unsigned char>(list[i][j])));
        list[i][len] = '\0';
    }
    for (int i = 0; i < n; ++i) {
        std::cout << list[i] << '\n';
        delete[] list[i];                            // avoid leaks
    }
}

Idiomatically safer (recommended): use std::string and std::vector<std::string> so manual allocation and delete[] are not needed:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> words;
words.reserve(n);
for (int i = 0; i < n; ++i) {
    std::string s;
    std::cin >> s;
    std::transform(s.begin(), s.end(), s.begin(),
                   [](unsigned char c){ return std::toupper(c); });
    words.push_back(std::move(s));
}
for (auto &w : words) std::cout << w << '\n';

Troubleshooting notes: always allocate strlen(...) + 1, iterate each stored string with its own strlen (or use std::string::size()), and cast to unsigned char when calling std::toupper to avoid undefined behavior on negative char values. If strange characters or numbers appear, that usually means a missing '\0' or an out-of-bounds read/write. Memory-checkers (valgrind or sanitizers) will quickly reveal such issues.

Recommended Answers

All 10 Replies

Hello. I'm working a bit different but i'll present you an valid algorithm

void up()
{
    char word;
        for(int i=0;i<=4;i++)
        {
            cin>>word;
            for(int j=0;j<strlen(word);j++)
                if(word[j]>='a'&&word[j]<='z')
                    cout<<word[j]-32;
                else
                    cout<<word[j];
        }
}

Hope it helps.

cout<<"enter a word => ";
cin>>tmpStr;
chPtrs[j] = new char[strlen(tmpStr)];
strcpy(chPtrs[j], tmpStr);

You don't need this. You also can input a whole string using fgets() or getline() functions.

After this, use a loop to traverse the string. Check if the character that is in consideration is lower or not using islower(). It is in cctype header file.

Hi,

I implemented this

void upperCase (char * chPtrs[5], char tmpStr[1000])
{
    for ( int j = 0; j<5; j++)
    {
        cout << "Enter a word => ";
        cin>>tmpStr;

        chPtrs[j] = new char[strlen(tmpStr)];
        strcpy(chPtrs[j], tmpStr);

    }
    for (int  j = 0; j<5; j++)
        cout <<chPtrs[j]<<endl;
    for (int  j = 0; j<strlen(tmpStr); j++)
        if (tmpStr[j] >= 'a' && tmpStr[j] <= 'z')
            cout <<tmpStr[j] - 32;
        else
            cout <<tmpStr[j];
}

This is the output that I'm getting.

befor calling reverse2( )...
 the string is Computerscience
After calling reverse2 function the string is:ecneicsretupmoc
Enter a word => cat
Enter a word => car
Enter a word => lion
Enter a word => tiger
Enter a word => cougar
cat
car
lion
tiger
cougar
677985716582Press any key to continue . . .

for (int j = 0; j<strlen(tmpStr); j++)
Why are you going through tmpStr? Isn't that simply the string you used on input? It has no bearing on your word list once input is done.

I have just modified the code:

void upperCase (char * chPtrs[5], char tmpStr[1000])
{
    for ( int j = 0; j<5; j++)
    {
        cout << "Enter a word => ";
        cin>>tmpStr;

        chPtrs[j] = new char[strlen(tmpStr)];
        strcpy(chPtrs[j], tmpStr);

    }
    for (int  j = 0; j<5; j++)
        cout <<chPtrs[j]<<endl;

    for (int  j = 0; j<strlen(tmpStr); j++)
        cout << (char)toupper(tmpStr[j]); 
}

But it's only converting the last word of the list to Uppercase. What should I do so it converts all the words on the list to Uppercases.

Thank you

Of course. Read my previous post.

WaltP,

I already remove the for (int j = 0; j<strlen(tmpStr); j++) and it's still only converting the last word to uppercase from the list

Then you still did something wrong. Since we can't see what has changed, we can't offer suggestions.

WaltP,

I modified the code like this:

void upperCase (char * chPtrs[5], char tmpStr[1000])
{
    for ( int j = 0; j<5; j++)
    {
        cout << "Enter a word => ";
        cin>>tmpStr;

        chPtrs[j] = new char[strlen(tmpStr)];
        strcpy(chPtrs[j], tmpStr);
    }

        for (int  j = 0; j<5; j++)
        {
            cout <<chPtrs[j]<<endl;
        }

        for (int  j = 0; j<strlen(*chPtrs); j++)
            {
                cout << (char)toupper(*(chPtrs[0]+j))<<" ";
                cout << (char)toupper(*(chPtrs[1]+j))<<" ";
                cout << (char)toupper(*(chPtrs[2]+j))<<" ";
                cout << (char)toupper(*(chPtrs[3]+j))<<" ";
                cout << (char)toupper(*(chPtrs[4]+j))<<endl;
            }

}

but it's cutting the words of. Like lion to lio, tiger to tig, bear to bea.

Thanks

chPtrs[j] = new char[strlen(tmpStr)]; -- you forgot the extra character for the trailing \0

for (int j = 0; j<strlen(*chPtrs); j++) -- what is the value of strlen(*chPtrs)? Do you really want the string lenght of a pointer? Wouldn't the length of a string be more useful?

And in that loop, why are you outputting exactly 5 characters? LION only has 4 characters, BAT has 3, MONKEY has 6. I'd suggest another loop, using strlen() of the string you are outputting.

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.