C++ change lowercase to Uppercase using a dynamic array - c++

I'm trying to use a Dynamic Array to change a lowercase word into an uppercase word. I ran into something I haven't encountered before called a "Heap Corruption". Can someone explain to me what I am doing wrong and possibly help fix this??
#include <iostream>
#include <cctype>
#include <new>
#include <string>
using namespace std;
int main()
{
int i;
int w;
char *p;
string str;
cout << "Change lowercase to UPPERCASE!" << endl;
cout << "Enter Word: ";
cin >> str;
w = str.length();
p = new (nothrow) char[w];
if (p == nullptr)
cout << "Error: memory could not be allocated" << endl;
else
{
cout << "Re-Enter Word: ";
cin >> p[w];
for (i = 0; i < w; i++)
cout << static_cast<char>(toupper(p[i]));
cout << endl;
}
delete[] p;
cout << "Press <Enter> to Exit";
cin.get();
return 0;
}

There's no need to use char* for conversion to upper case. Instead you could use std::transform like here:
transform(str.begin(), str.end(), str.begin(), ::toupper);
cout << str << endl;
--- edit ---
If, for whatever (academic) reason, you want to perform the conversion to upper case on a dynamically allocated char array, then you could still use std::transform for that.
However, as you see in the snippet below, you need to allocate one extra character for the trailing \0-char which signals end of string.
char* szStr = new char[w+1];
std::transform(str.begin(), str.end(), szStr, ::toupper);
szStr[w]='\0';
cout << szStr << endl;

you made so many mistakes, but to just answer your question:
p = new (nothrow) char[w + 1];
this is so that we will have room for the null termination character ('\0')
and also use:
cin >> p;

Related

checking for character pair in array

I have a character array that produces a random array of lowercase letters in the length that the user inputs. my problem is that after the array of random letters is produced the user inputs a pair of charaters(two letters) and my code should check if that pair is in the random array that was produced. it worked fine when it just checked for one letter but when i introduced the second one it does not work.I would appreciate any help.
#include <ctime>
#include <iostream>
#include <cstdlib>
int main() {
std::srand(std::time(NULL));
int i, num;
char letter1, letter2, ch, r;
const char chars[]="abcdefghijklmnopqrstuvwxyz";
std::cout << "How many letters do you want in your string? ";
std::cin >> num;
for (i=0; i<num; i++)
{
ch = chars[rand()%26];
std::cout << ch;
}
std::cout << "\nWhat letter pair would you like to find? ";
std::cin >> letter1 >> letter2;
if ((chars[i] == letter1) && (chars[i+1]==letter2))
std::cout << "It is in your string. ";
else
std::cout << "You do not have " << letter1 << letter2 << " in your string";
}
First, you are not storing your randomly generated chars
for (i=0; i<num; i++)
{
ch = chars[rand()%26];
std::cout << ch;
}
This just writes a random char in ch and displays it on the console with each iteration. You don't store your data, ch just contains the last random char after your loop ends and everything else is lost.
The part where you want to search is double wrong.
if ((chars[i] == letter1) && (chars[i+1]==letter2))
std::cout << "It is in your string. ";
else
std::cout << "You do not have " << letter1 << letter2 << " in your string";
This isn't inside a loop, i is simply always going to be num-1.
The array you are checking is chars which is your const array containing "abcdefghijklmnopqrstuvwxyz". This doesn't contain your randomly generated chars.

Check letters against the word of an arbitrary size in a Hangman game

Currently I am working on a hangman game, I had previously coded it to only work for a 5 letter word, but now would like to make it handle any length of word, how could I change this code to make it work how I want it to?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include <cstdlib>
using namespace std;
int main()
{
string word;
int tries;
string guess;
string wordguess;
string output;
cout << "Enter a word for player two to guess: ";
cin >> word;
system("CLS");
cout.flush();
cout << "Guess the word!" << endl;
for (int i = 0; i < word.length(); i++)
{
cout << "_ ";
}
cout << "Enter a letter: ";
cin >> guess;
for (int tries = 5; tries > 0; tries--)
{
if (guess[0] == word[0]) {
output[0] = word[0];
cout << "You guessed the first letter! Good job!" << endl;
}
if (guess[0] == word[1]) {
output[2] = word[1];
cout << "You guessed the second letter! Good job!" << endl;
}
if (guess[0] == word[2]) {
output[4] = word[2];
cout << "You guessed the third letter! Good job!" << endl;
}
if (guess[0] == word[3]) {
output[6] = word[3];
cout << "You guessed the fourth letter! Good job!" << endl;
}
if (guess[0] == word[4]) {
output[8] = word[4];
cout << "You guessed the fifth letter! Good job!" << endl;
}
cout << output << endl;
cout << "You have " << tries << " tries left. Take a guess at the word: " << endl;
cin >> wordguess;
if (wordguess == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
}
system("pause");
return 0;
}
As you can tell I was checking each position from 0 to 4 (first through fifth letter). I know there are plenty of ways that I could have coded this better but as you can guess, I am new to coding and this is the way I thought of it. Please note this is still a work in progress so it is not fully complete. Any help would be great!
When designing an algorithm, think of how you would do this by hand, without a computer. Then let the code do the same.
If you were checking your friend's guess against a word written on sand, you would probably go about it like this:
go through the written pattern character by character, pronouncing your word in memory
for each letter, check if it is equal to the guess
if it is
replace the placeholder with it
memorize that your friend guessed right.
Also note if there are any placeholders left
if there aren't, your friend wins
finally, if your friend didn't guess right, score them a penalty point and check if they lose
Now, all that leaves is to put this down in C++. The language provides all sorts of entities - let's check which ones fit ours needs the best:
the word and the current pattern - strings of a fixed size
bits to memorize:
whether the current guess is right - bool
placeholders left - int
penalty points (or, equivalently, attempts left) - int
parts of the algorithm:
looping over a string - for loop of one of a few kinds
we need to replace the character in the pattern at the same index as the guessed letter in the word. So, we need to have the index when looping. Thus the flavor with the index variable, for(std::string::size_type i = 0; i < str.size(); ++i) probably fits the best.
// Example program
#include <iostream>
#include <string>
using namespace std;
class my_game
{
private:
string congrats_array[15] = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "nineth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth"};
string word_to_guess;
int tries_left;
int word_length;
int letters_guessed_count;
string guessed_letters;
void check_letter(char letter);
void print_current_word_state();
public:
my_game();
void begin_the_game();
void play_the_game();
};
my_game::my_game()
{
}
void my_game::begin_the_game()
{
cout << "Enter a word for player to guess: " << endl;
cin >> word_to_guess;
system("CLS");
cout.flush();
cout << "Enter the tries amount!\n" << endl;
cin >> tries_left;
word_length = word_to_guess.size();
guessed_letters = "_";
letters_guessed_count = 0;
for(int i = 0; i < word_length - 1; i++){
guessed_letters += "_";
}
}
void my_game::play_the_game()
{
cout << "Guess the word!" << endl;
char letter;
for(int i = 0; i < tries_left; i++)
{
cout << guessed_letters << endl;
cout << "Enter a letter: " << endl;
cin >> letter;
check_letter(letter);
if(letters_guessed_count == word_length){
cout << "Congrats! You won!" << endl;
return;
}
}
cout << "You lose" << endl;
}
void my_game::check_letter(char letter)
{
for(int i = 0; i < word_length; i++)
{
if(word_to_guess[i] == letter && guessed_letters[i] != letter)
{
guessed_letters[i] = letter;
letters_guessed_count++;
cout << "You guessed the" << congrats_array[i] <<"letter! Good job!" << endl;
}
}
}
int main()
{
my_game game;
game.begin_the_game();
game.play_the_game();
}
So, in short what you need to do this with words of any arbitrary length is to use string's .substr() function and the stringstream library's .str() and << and >> operators. This version of your code uses a function that inserts a correctly guessed character at the appropriate indexed location. This will gradually replace the "_________" with letters at the correct places. This is much easier to do in Java, but stringstream is a good library I would highly recommend getting familiar with it. I'll leave the problem of how to handle multiple instances of a guessed character up to you (ie 'i' in "bibliography")
#include <string>
using std::string;
#include <sstream>
using std::stringstream;
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
string newString(string, int, string);
int main()
{
string word;
string guess;
int tries;
string output;
string input;
cout << "Enter word for player 2 to guess: ";
cin >> word;
stringstream ss;
//---------- fills the stream with "_"s matching the length of word
for(int i = 0; i < word.length(); i++)
ss << "_";
//----------- assigns the initial value of "___..." to output
ss >> output;
//----------- sets up the loop
tries = 5;
bool found = false;
for(int i = 0; i < 5; i++)
{
cout << "\nTry " << i << " of 5: Enter a letter or guess the word: ";
cin >> input;
if(input == word)
{
cout << "Congratulations, you guessed the word correctly!" << endl;
break;
}
//------------------ else, proceed with replacing letters
if(word.find(input) != std::string::npos)
{
size_t position = word.find(input); // finds index of first instance of the guessed letter
cout << "You guessed the " << position+1 << " letter! Good job!" << endl; // since strings start at index 0, position+1
//------- replaces appropriate "_" with the guessed letter
output = newString(input, position, output);
cout << "\n" << output;
// Around here you'll want to set up a way to deal with multiple instances
// of the same letter
}
else
cout << "Incorrect guess" << endl;
}
return 0;
}
//---------------------------------------------------
string newString(string guess, int index, string word)
{
string NewString;
stringstream temp;
//---------- hack up the string into sections before and after the index
string before = word.substr(0, index);
string after = word.substr(index+1, word.length() - index+1);
//---------------- populates the new stringstream and assigns it to the result
temp << before << guess << after;
NewString = temp.str();
return NewString;
}

How to find number of characters in dynamic array c++

I am very much a beginner at C++, and I've been trying for the past 6 hours to try to figure out how to get the number of characters in a dynamic array.
This is the code I have:
using namespace std;
int array_size;
typedef char* charPtr;
charPtr a = new char[array_size];
char *p=a;
int len(char p[]) {
int count = 0;
while (*p != '\0'); {
count++;
p++;
return count;
}
}
int main() {
cout << "Type a phrase" << endl;
cin >> array_size;
cout << "Your phrase was " << len(p) << " characters long." << endl;
return 0;
}
Any help would be greatly appreciated!
You have to remove the semicolon (;) after the temination condition of your while loop. ; is the end of an statement, after that a new statment beginns. Apart from this your return statement would be inside the while loop. Remove it outside the loop. Adapt your code like this:
int len(char p[]) {
int count = 0;
while (*p != '\0')
{
count++;
p++;
}
return count;
}
Further you have to read a string from input into your dynamicly allocated array of char:
int main() {
int array_size = 100;
char *p=new char[array_size]; // allocate memory
cout << "Type a phrase" << endl;
cin >> p; // read string into allocated memory
cout << "Your phrase was " << len(p) << " characters long." << endl;
delete p; // free memory
return 0;
}
The function strlen gives you the length of a \0-terminated string.
#include <string.h>
int main() {
int array_size = 100;
char *p=new char[array_size]; // allocate memory
cout << "Type a phrase" << endl;
cin >> p; // read string into allocated memory
cout << "Your phrase was " << strlen(p) << " characters long." << endl;
delete p; // free memory
return 0;
}
But I recommend to use std::string:
#include <string>
int main() {
std::string str;
cout << "Type a phrase" << endl;
cin >> str;
cout << "Your phrase was " << str.size() << " characters long." << endl;
return 0;
}
std::string represents a sequences of characters with dynamic length.
Getting the size of dynamically allocated array
A dynamically allocated array does not have any information about its size that is available in a standards compliant way.
We are able to compute the length of C style strings since there is sentinel element, '\0', to mark the end of the string. There are no such elements for other types.
Even then, you cannot compute the size of an array of characters allocated using heap memory like you have.
Problems with posted code
You have the following lines outside all functions.
int array_size;
typedef char* charPtr;
charPtr a = new char[array_size];
char *p=a;
They are executed before anything in main gets executed. When these lines are executed, array_size gets initialized to 0. Then you allocate memory for charPtr using 0 as the value of array_size.
Function len has an error due to a typo, which could lead to either (a) a hanging program or an incorrect return value.
int len(char p[])
{
int count = 0;
while (*p != '\0');
// ^^^ The semicolon is a problem
{
count++;
p++;
return count;
}
}
If *p is not equal to '\0', the program will never get out of the while statement. It will hange.
If *p is equal to '\0', the program will get out of the while statement but it will still execute the the lines after that. As a consequence, you will end up returning 1 as the length where 0 is the right answer.
In main, you have:
cout << "Type a phrase" << endl;
cin >> array_size;
When the user sees the output, they will try to enter a phrase. However, array_size is an int. There is a mismatch between the prompt to the user and the line to read the data.
You could change it them to:
cout << "Type array size" << endl;
cin >> array_size;
cout << "Type a phrase" << endl;
That is one step better but that still does not change the fact that memory for a was allocated using a size of 0.
Using uninitialized memory
You are calling len(p) in the cout line but the elements of p have not been initialized.
It's not clear from your post what the program is supposed to do. I am guessing that you want to read a phrase from stdin and write it out to stdout. You can use the following simplified version for that.
int main()
{
std::string phrase;
cout << "Type a phrase" << endl;
// Get the entire line as a phrase.
std::getline(std::cin, phrase);
cout << "Your phrase is " << phrase << endl;
cout << "It is " << phrase.size() << " characters long." << endl;
return 0;
}
First problem: you cannot use array_size till it has been initialized.
char* a = new char [array_size]
since array_size has not been initialized and has garbage data in it, you have no idea how big that array is going to be.
that's why first you have to initialize array_size, and only after allocate your char array.
like
int array_size = 0 //no reason to have this variable as global, but that's up to you
char *a = nullptr; //same
int main()
{
cin >> array_size;
if (array_size <= 0) //make sure the input is valid and not negative
return 0;
a = new char[array_size];
//now you can work on your newly allocated array of characters
//the number of characters the array has equals to the array_size variable.
delete[] a;
return 0;
}
your len function checks for a '\0' character, but again, you have not initialized that char array either, so it contains garbage data. therefore sometimes you may get a result of len 5, 10, 502043, anything can happen really (undefined behavior).

First word of a phrase is dropped when I try and put it in a vector?

Sorry for the vague header. Difficult to describe. I am trying to get a phrase from the user and put that phrase into a vector, word by word, separated by spaces. For some reason when the vector is printed it completely leaves out the first word of the phrase, if that makes sense. Here's the code I have so far:
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
do{
cin >> phraseInput;
if(phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
}
}while(phraseInput != stop);
}
Here you have taken input for two times only first one skipped
Now you should change this
else{ string temp;
getline(cin, temp);
phraseInput+=temp;
istringstream iss(phraseInput);
//.....
I think I found your answer
I tested your code with the phrase "this is line."
Your variable "phraseInput" first take "this" string.
After getline(cin, phraseInput) line.
Your variable "phraseInput" take "is line" string.
Therefore when it prints, it simply skips the first keyword.
Result is: the first string "this" is missing
I think in this way: You take two input from user.
Therefore I thought " What happens if I commented first cin? "
After commented on your first cin. I got all the string in variable "phraseInput"
Result is:
Then I thought "do while" loop also unnecessary, since it prints any word it took from user.
I also commented your "do while" loop
Here is the final version of your code.
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
/*do{
cin >> phraseInput;
if (phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {*/
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
//}
system("pause");
//} while (phraseInput != stop);
}

Write a name in a diagonal line representation

I'm trying to write a program that will show a name in a diagonal line.
I know I should add a variable with space, like \t, and increment it in each loop.
I have tried to do this with no success. Any suggestions?
int main()
{
string space = "\t";
string firstName;
cout << "Enter your first name:";
cin >> firstName;
for (int posChar = 0;
posChar < firstName.length( );
posChar++)
cout << space << firstName.at(posChar) << endl;
space=space + "\t"; // this is what I've tried, it's a long shot.
return 0;
}
output:
Enter your first name:Alexander
A
l
e
x
a
n
d
e
r
If you would indent you code properly, you would see that space=space + "\t"; is not part of the for.
Also, you should use a space instead of a tab.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string space;
string firstName;
cout << "Enter your first name:";
cin >> firstName;
for (int posChar = 0; posChar < firstName.length( ); posChar++)
{
cout << space << firstName.at(posChar) << endl;
space = space + " ";
}
return 0;
}
You could submit some of your code (not necessarily this one) to code review. You have some bad practices when it comes to formatting and (lack of) indenting.
Need { } on your for loop. Without it you are not adding the tab for each character but instead add it when the loop is complete.
If you do a for loop without a block then only the command following the loop is executed.
Did you forget the opening and closing brackets for the code block?
The loop you wrote only does
cout << space << firstName.at(posChar) << endl;
and after it has finished it does once
space=space + "\t"; // this is what I've tried, it's a long shot.
It should look like this:
for (int posChar = 0;
posChar < firstName.length( );
posChar++)
{
cout << space << firstName.at(posChar) << endl;
space=space + "\t"; // this is what I've tried, it's a long shot.
}