1

So i have a hw problem for my class where i have to store ten names, capitalize them and then sort them alphabetically. We just started using strings and there are some things that are still a little confusing to me. This code can store all the names in a string array, but the UpperCase seems to not be working. I dont know for sure but i think it is because I have second for loop running cap amount of times, which would be 10. And since not every string will have 10 elements, i'm running into problems?..Is that it or is it something else? Well i tried to fix this by using the .length (function?), to find the length of each name in the array, but I always get errors. Any help is appreciated, thanks!

#include<iostream>
#include<string>
using namespace std;

void UpperCase(string names[],int cap);

void print(string names[],int cap);
void swap(string names[],int &x,int &y);

string names[10];

int main(){
    char a;
    cout<<sizeof(a);
    for(int i=0;i<10;i++){
        cout<<"Enter a name for student "<<i+1<<" : ";
        cin>>names[i];
        cout<<endl;
    }

    UpperCase(names,10);
    cout<<endl;
    print(names,10);

    cout<<endl;
    print(names,10);

    return 0;
}

void print(string names[],int cap){
    for(int i=0;i<cap;i++)
        cout<<names[i]<<endl;
}

void UpperCase(string names[],int cap){
for(int student=0;student<cap;student++){
    for(int letter=0;letter<names[student].length();letter++){
        if(names[student][letter]>='a')
            names[student][letter]-=('a'-'A');
    }
}

}

tyler16
  • 73
  • 6
  • Is the STL out of the questions? – Ed Heal May 10 '14 at 17:34
  • 2
    You're right about `cap` being the wrong termination condition for the inner loop in `UpperCase()`, and `.length()` being right, so please show your code for the latter. Separately: What happens if a name contains the character `a`? – j_random_hacker May 10 '14 at 17:37
  • 1
    Funny that you would be using `std::string` and then using arrays instead of the much superior container classes. – Fred Larson May 10 '14 at 17:38
  • Two things I should mention: perhaps [this article](http://www.learncpp.com/cpp-tutorial/66-c-style-strings/) will help you (hint: null terminator). Secondly, your if statement in `UpperCase` doesn't check if it's `> 'z'` either. – Qix - MONICA WAS MISTREATED May 10 '14 at 17:38
  • I think T.C.'s answer is very helpful but in general it would help if you told us specifically what did not work. Did it compile? Did it run? Did it produce output? If so, what exactly was wrong with it? If either of the steps fails it's essential for us to know where and in which way. I'm sure if you produce this information (e.g. learn how to use a debugger and obtain a stack trace) you're more than half way to solving the issue yourself. – Peter - Reinstate Monica May 10 '14 at 17:47
  • Alright thanks for all the quick answers. Whenever i tried to figure out the length of each string i would write names[student].length without the parentheses, so i now have that figured out. Qix thanks for the article! But is still don't get why it doesnt check if it's greater than 'z'? – tyler16 May 10 '14 at 18:35
  • You should be checking whether your character is _between_ `'a'` and `'z'`, inclusive. The characters `'{'`,`'}'`,`'|'` and `'~'` are all > `'z'` in ASCII, but shouldn't be changed. – Useless May 10 '14 at 18:43
  • Since these are supposed to be names, he could probably get away with it...at least, until little Bobby Tables or a cousin comes along... – T.C. May 10 '14 at 18:50

2 Answers2

3

Your inner loop should be iterating for the length of the string. string::length() is a function, not a field, so you need the parentheses. There's also a standard library function for converting a character to upper case.

#include <cctype>
using std::toupper;

void UpperCase(string names[],int cap){
    for(int student=0;student<cap;student++){
        for(int letter=0;letter<names[student].length();letter++){
            names[student][letter] = toupper(names[student][letter]);
        }
    }
}
T.C.
  • 133,968
  • 17
  • 288
  • 421
1

..., but the UpperCase seems to not be working

So write a minimal program that just calls UpperCase on known input. It makes it easy to debug, and would also make a much better question. We don't need to see the print or swap to help with that, and prompting the user for input isn't relevant to whether UpperCase works or not.

Having said that, you should use std::string::length() - however, you say

Well i tried to fix this by using the .length (function?), to find the length of each name in the array, but I always get errors

but don't show what you actually tried, or what the errors were.


Here's a minimal, complete and self-contained program, using std::toupper as per T.C.'s answer. I changed it to demonstrate more modern style, and to show there are easier ways to confirm your functions work than to write a whole program and then find out it's broken.

#include <algorithm>  // for transform, for_each
#include <cctype>     // for toupper
#include <string>
#include <vector>     // easier to use (correctly) than bare arrays

// change a string to upper case
void str_toupper(std::string &s) {
    std::transform(s.begin(), s.end(),
                   s.begin(),
                   [](char c) -> char { return std::toupper(c); });
}
// change a vector of strings to upper case
void vec_toupper(std::vector<std::string>& v) {
    std::for_each(v.begin(), v.end(), str_toupper);
}

using namespace std;
int main() {
    vector<string> const input = { "bob", "alice cooper", "Eve" };
    vector<string> const expected = { "BOB", "ALICE COOPER", "EVE" };

    vector<string> working = input;
    vec_toupper(working);
    return working == expected ? 0 : -1;
    // use cout or debugger to solve problem only if program returns nonzero
}
Useless
  • 64,155
  • 6
  • 88
  • 132
  • gcc 4.8.2 doesn't find a valid overload without some help ... I can replace it with `(int (*)(int)) std::toupper`, but I think that's uglier and harder to read than the lambda. – Useless May 10 '14 at 18:40
  • Just use ::toupper instead of std::toupper, then no cast is needed. There's a version in locale as well, perhaps that's the one it's mixing with which the cast resolves. There's a brief discussion on it here: http://stackoverflow.com/a/7131881/3332992 – imbtfab May 10 '14 at 19:34
  • Hmm, that relies on the C version (from ``) - and the second half of the answer suggests the ugly cast instead. – Useless May 10 '14 at 20:02