C++ "toupper" not converting character to uppercase - c++

I'm trying to convert every letter in a string to uppercase. I'm looping through each character and using toupper on it. However, when I print the new string out, it's not working. Sorry if this is a newbie question. Any help would be greatly appreciated :)
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string str1, str2;
cin >> str1 >> str2;
int len = str1.size();
for (int i = 0; i < len; i++) {
toupper(str1[i]);
toupper(str2[i]);
cout << str1[i] << " " << str2[i] << endl;
}
}

std::toupper returns a value rather than modifying its argument. So you need to do:
str1[i] = std::toupper(str1[i]);
str2[i] = std::toupper(str2[i]);
in order to actually modify the strings.
If you turn on warnings, e.g with -Wall the compiler will tell you that your version of the code has no effect.

This may be better, depending on your coding standards:
std::transform(str1.begin(), str1.end(), str1.begin(), std::toupper);
std::transform(str2.begin(), str2.end(), str2.begin(), std::toupper);
The above uses the STL function transform to convert the string to all uppercase.

You need to save the modified strings back into the str arrays. Something like this:
str[i] = toupper(str[i]);

In your loop, you don't change the elements of the strings because toupper() returns a new character, it doesn't change the passed character. You need to make your elements be the same as the returned characters, as follows:
for (int i = 0; i < len; i++) {
str1[i] = toupper(str1[i]);
str2[i] = toupper(str2[i]);
cout << str1[i] << " " << str2[i] << endl;
}

For starters this loop
for (int i = 0; i < len; i++) {
toupper(str1[i]);
toupper(str2[i]);
cout << str1[i] << " " << str2[i] << endl;
}
can invoke undefined behavior because the strings str1 and str2 in general can have different lengths.
These calls
toupper(str1[i]);
toupper(str2[i]);
has no effect because they change neither str1[i] no str2[i].
Also you need to convert the argument of a call of toupper to the type unsigned char.
You could separately output each string the following way
for ( unsigned char c : str1 )
{
std::cout << ::toupper( c );
}
std::cout << ' ';
for ( unsigned char c : str2 )
{
std::cout << ::toupper( c );
}
std::cout << '\n';

Related

How do I Change String Array into Char Array?

Okay. I have taken a sentence and split into an array thus far with this code I found online:
string strWords[5];
short counter = 0;
for(short i =0; i<texttoChange.length();i++)
{
strWords[counter] +=texttoChange[i];
if(texttoChange[i] == ' ')
{
counter++;
}
}
for(short i=0;i<5;i++)
{
cout << strWords[i] << "(" << strWords[i].size() << ")" << endl;
}
Now I want to take strWords[i] and split that array into an array of characters or single letter string array. Is it Possible?
Assuming you need a c style array, you can do,
char *charArray = strWords[i].c_str();, you can get the size by strlen(charArray)
otherwise there is no point of converting string to char array.

atoi() Not Working with std::string::substr()

This is a snippet of my code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h> // atoi()
int main() {
std::string line;
std::ifstream numbers("numbertest.txt");
if (numbers.is_open()) {
while (std::getline(numbers, line)) {
for (int i = 0; i < line.length() - 4; i++) {
for (int n = 0; n < 5; n++) {
std::cout << atoi((line.substr(i, 5)[n]).c_str());
}
I want to operate with numbers in groups of 5, from a file. Why is atoi() not working here? It says "expression must have class type" under the second parentheses on the atoi line.
line.substr(i, 5) creates a temporary std::string containing 5 characters in line from position i
std::string foo = "hello world";
int i = 2;
std::cout << foo.substr(2, 5) << '\n';
would print "llo wo".
The [n] operator returns the nth character of the substring, which is of type char, you are then calling .c_str() on that character rather than on the substring.
You can avoid the .c_str() entirely by using std::stoi, e.g.
std::cout << "line.substr(i, 5) = " << line.substr(i, 5) << '\n';
std::cout << std::stoi(line.substr(i, 5));
aoti and stoi both take a string representation of a number as their input and return the numeric value. For example:
std::string input = "123a";
// std::cout << input * 10 << '\n'; // illegal: input is a string, not a number.
int i = std::stoi(input); // converts to integer representation, i.e. 123
std::cout << i * 10 << '\n'; // outputs 1230
----- EDIT -----
You're actually asking all the wrong questions. What you want to do is take an input pattern and output all of the patterns of 5 characters in it.
Example input: "1020304050"
Example output: 10203 02030 20304 03040 30405 04050
You don't need to convert these to numbers to output them, you can just output the characters. The problem with your original code wasn't the conversion it was the incorrect sequence of operators.
std::substring is expensive, it has to create a new, temporary string, copy characters from the original into it, and then return it, and it does it for every call.
The following should achieve what you're trying to do:
while (std::getline(numbers, line)) {
for (size_t i = 0; i < line.length() - 4; i++) {
for (size_t n = 0; n < 5; n++) {
std::cout << line[i + n];
}
std::cout << '\n';
}
}
If you really want to invoke substr, you could also implement this as
while (std::getline(numbers, line)) {
for (size_t i = 0; i < line.length() - 4; i++) {
std::cout << line.substr(i, 5) << '\n';
}
}
Here's a working demonstration: http://ideone.com/mXv2z5
Try atoi( line.substr(i,5).c_str() )
Or if you want for each character
std::cout << ((line.substr(i, 5)[n]) - '0');
Or even better
std::cout << (line[i+n]) - '0');
Note that: atoi is not ascii to integer. It converts a ctype string to number. For a single character, this conversion should be done using arithmetic or lookup table.
Also there is no point converting characters to integer and then print it (back to chacters). You should better print digit character itself.
Moreover in C++, I would prefer to use stringstream instead or atoi. On C++11 there are even more advanced solutions like sto*.

'Try This' exercise on Programming Principles and Practice Using C++, For iteration

I'm studying in this book (self study) and I'd really appreciate if you could help me with a little 'try this' exercise.
This is the code I wrote:
#include "../../../std_lib_facilities.h"
int main()
{
for (char i ='a'; i <='z'; ++i) {
int x = i;
cout << i << '\t' << x << '\n';
}
keep_window_open();
return 0;
}
The next step, according to the book, is: "[...] then modify your program to also write out a table of the integer values for uppercase letters and digits"
Is there a function to do that, or do I simply have to repeat the loop starting from A?
Thanks
Yes, repeat the loop from 'A' to 'Z' and '0' to '9'.
Assuming your book has covered functions (which it may not have), you might refactor your for loop into its own function perhaps called displayCharactersInTable which takes as arguments the first character and last character. Those would replace the use of 'a' and 'z' in the loop. Thus your main function would look like:
...
displayCharactersInTable('a', 'z');
displayCharactersInTable('A', 'Z');
displayCharactersInTable('0', '9');
...
const char lc_alphabet[] = "abcdefghijklmnopqrstuvwxyz";
const char uc_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int main() {
for (const char *cur = lc_alphabet; cur < lc_alphabet + sizeof(lc_alphabet); ++cur)
std::cout << *cur << \t << (int)*cur << '\n';
for (const char *cur = uc_alphabet; cur < uc_alphabet + sizeof(uc_alphabet); ++cur)
std::cout << *cur << \t << (int)*cur << '\n';
return 0;
}
This code does not assume that character representations are contiguous (or even increasing alphabetically), so it will work for all character encodings.
int b = 97; // the corresponding decimal ascii code for 'a'
int a = 65; // the corresponding decimal ascii code for 'A'
for(int i = 0; i < 26; ++i)
cout << char('A' + i) << '\t' << a << '\t' << char('a' + i) << '\t' << b << '\n'; //print out 'A' and add i, print out a, print out 'a' and add i, print out b
++a; //increment a by 1
++b; //increment b by 1

Error in my function (split Sentence)

I have problem in my split Sentence function .
The idea of ​​my function split any Sentence and add it to array like
Example:
Sentence:: Hello world.
My function will works:: (array[0]= hello, array[1]= world).
This is my code
void splitSentence(char *Sentence, char symb){
const int Size = strlen(Sentence);
string SentenceResult[2];
int count= 0;
stringstream stream;
for(int i=0;i<Size;i++){
stream << Sentence[i];
if((Sentence[i] == symb) || (Sentence[i] == '\0')){
SentenceResult[count] = stream.str();
count++;
stream.str(" ");
}
}
cout << "Stream: " << stream.str() << endl;
cout << "Word [0]: " << SentenceResult[0] << endl;
cout << "Word [1]: " << SentenceResult[1] << endl;
}
The result
Stream: world
array [0]: hello
array [1]: // empty (must be "world")
What the problem in my function.
Why array[1] is empty .
const int Size = strlen(Sentence);
This calculates the length of the string data, but not the final null terminator, so your loop will not find the terminator, and won't include the last word. You want to add one to this value to get the full length of the terminated string.
Your for loop does not run far enough to get to the Sentence[i] == '\0' case. It will only run up to the "d" of "hello world", so the conent of the stream is not written anymore into the output array.
You could for example write:
const int Size = strlen(Sentence)+1;
and you have included the final null byte.
You just need to change your for loop:
for(int i=0; i <= Size; i++)

I am trying to return a Character Array but, I'm only getting the first letter returned

I'm working on a small little thing here for school. After hours of researching, and a ton of errors and logic reworking I've almost completed my little program here.
I'm trying to take user input, store it into the string, get a character array from the string ( dont ask why, I just have to put this into a character array ), then get the reversed order of the phrase that the user entered. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <String>
#include <cstring>
using namespace std;
using namespace System;
#pragma hdrstop
char* getCharArray(string);
string reversePhrase( int, char* );
void main(void)
{
string sPhrase = "";
int sSize = 0;
string sReversed = "";
char* cPhrase = NULL;
cout << "Welcome to the You Type It & We'll Reverse it! [Version 1.0] " << endl;
cout << "This program will reverse your phrase, and count how many characters are in it!" << endl;
cout << "To begin just enter a phrase." << endl;
cout << "Enter a phrase: ";
getline( cin, sPhrase);
sSize = sPhrase.length();
cout << endl;
cPhrase = getCharArray(sPhrase);
sReversed = reversePhrase( sSize, cPhrase );
cout << sReversed;
system("pause");
}
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
int place = size;
for ( int i = 0; i < size ; i ++ )
{
sReversed.append(1, cPhrase[place]);
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size];
for (int i = 0 ; i < size ; i++)
{
cArray[size] = sPhrase.at(i);
}
return cArray;
}
When I type in "ownage" into the program, this is what I get returned:
It is almost like my Character Array is getting garbage collected before it can use all of the characters. This is probably an easy fix but, I just don't see how I can get around this one.
Try rewriting getCharArray like this
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size+1]; // NOTE
for (int i = 0 ; i < size ; i++)
{
cArray[i] = sPhrase.at(i); // NOTE
}
}
cArray[size]=0; // NOTE
return cArray;
}
Note that the assignment in the loop now uses the index variable. Also, you need to allocate one extra char in the array to set the null terminator for the string and then you need to set it at the end.
You'll also need to think about deallocating the array at some point
The bug is in this line:
cArray[size] = sPhrase.at(i);
That size should be your loop index.
You should probably look at using std::string more, and not poke around with character arrays when there's no need to.
Why use a char array at all? It's not only useless – it complicates the code substantially (the usage of your function is more difficult, and you've forgotten to free the memory allocated by new!). Why not just have the following function:
string reverse(string const& input);
(Passing the argument by const reference instead of by value saves you a copy!)
In fact, implementing the function only takes a single line using the features of the string class (one of its constructors takes two iterators):
string reverse(string const& input) {
return string(input.rbegin(), input.rend());
}
reversePhrase is also not correct. Try something like this:
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
sReversed.resize(size);
int place = size - 1;
for ( int i = 0; i < size ; i ++ )
{
sReversed [i] = cPhrase[place];
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
First, start the array with -1. After that, use a for loop with -1 and increment inside the loop. Then, you can get the first element of the array.