I'm trying to use CStrings to do miscellaneous tasks in C++, such as remove all the vowels from the name provided. However, I can't seem to figure out why I'm getting this error:
Stack around the variable "name" was corrupted.
Why is this happening?
Here is the code:
#include <iostream>
#include <iomanip>
#include <cstring>
#include <string>
using namespace std;
void cStringDemo();
void stringDemo();
void removeCVowels(char myGuess[50]);
int main() {
cStringDemo();
cin.get();
cin.ignore();
}
void cStringDemo() {
char name[] = "Seth Smith";
char guess[50];
cout << "Guess my name! [First and Last, EX: Bobby Hall.]" << endl;
cin.get(guess, 20);
if (strcmp(name, guess) == 0) {
cout << "Correct!" << endl;
}
else {
cout << "Incorrect!" << endl;
}
cout << "You guessed " << guess << "." << endl;
removeCVowels(guess);
}
void removeCVowels(char myGuess[50]) {
char nameNoVowel[50];
strcpy_s(myGuess, 100, nameNoVowel);
for (int x = 0; x < 50; x++) {
if (nameNoVowel[x] == 'a' || nameNoVowel[x] == 'e' || nameNoVowel[x] == 'i' || nameNoVowel[x] == 'o' || nameNoVowel[x] == 'u' || nameNoVowel[x] == 'A' || nameNoVowel[x] == 'E' ||
nameNoVowel[x] == 'I' || nameNoVowel[x] == 'O' || nameNoVowel[x] == 'U')
{
nameNoVowel[x] = ' ';
}
}
}
This is undefined behavior:
void removeCVowels(char myGuess[50]) {
char nameNoVowel[50];
strcpy_s(myGuess, 100, nameNoVowel);
You are copying from uninitialized nameNoVowel to myGuess. You should swap the arguments of strcpy_s. Also, even if you swap the two arguments of strcpy_s, the limit of 100 is also too big, since nameNoVowel is only 50 chars. Try:
void removeCVowels(char myGuess[50]) {
char nameNoVowel[50];
strcpy_s(nameNoVowel, sizeof(nameNoVowel)-1, myGuess);
There are a few problems in the code that you posted. Below is code fixed with explanation in comments of what was wrong:
void cStringDemo() {
char name[] = "Seth Smith";
char guess[50] = {0}; //in here initialize the table with zeros
cout << "Guess my name! [First and Last, EX: Bobby Hall.]" << endl;
cin.get(guess, 20); // I am not sure why you want 20 characters and have array of size 50
if (strcmp(name, guess) == 0) {
cout << "Correct!" << endl;
}
else {
cout << "Incorrect!" << endl;
}
cout << "You guessed " << guess << "." << endl;
removeCVowels(guess);
}
void removeCVowels(char myGuess[50]) {
char nameNoVowel[50] = {0}; //it is always good to initialize variables
strcpy_s(myGuess, 50, nameNoVowel); //here lies the problem you tried to copy 100
// characters from array size of 50 this leads
//to undefined behaviour of your program and stack corruption
for (int x = 0; x < 50; x++) {
if (nameNoVowel[x] == 'a' || nameNoVowel[x] == 'e' || nameNoVowel[x] == 'i' || nameNoVowel[x] == 'o' || nameNoVowel[x] == 'u' || nameNoVowel[x] == 'A' || nameNoVowel[x] == 'E' ||
nameNoVowel[x] == 'I' || nameNoVowel[x] == 'O' || nameNoVowel[x] == 'U')
{
nameNoVowel[x] = ' ';
}
}
}
Related
I need to write a program where I enter 2 letters and it should display "Yes" if both letters are vowels or consonants. If they are different types it should display "NO".
At the end it should display the 2 entered vowels and consonants separately.
I've tried this code but it doesn't work for NO. Can you help me fix it?
#include <iostream>
using namespace std;
int main()
{
char a = 'a';
char b = 'b';
cout << "enter first charcter: " << endl;
cin >> a;
cout << "enter second character: " << endl;
cin >> b;
if ((a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') && (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u'))
{
cout << "YES" << endl;
}
else if ((a != 'a' || a != 'e' || a != 'i' || a != 'o' || a != 'u') && (b != 'a' || b != 'e' || b != 'i' || b != 'o' || b != 'u'))
{
cout << "YES" << endl;
}
else if ((a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u') && (b != 'a' || b != 'e' || b != 'i' || b != 'o' || b != 'u'))
{
cout << "NO" << endl;
}
else if ((a != 'a' || a != 'e' || a != 'i' || a != 'o' || a != 'u') && (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u'))
{
cout << "NO" << endl;
}
return 0;
}
There is one issue in your second YES case and likely every consonant check. You are using logical OR, when it should be logical AND. Your character a can't be 'a' AND it cannot be 'e' AND etc. If a = 'e', it's still not the other vowels, and your big logical OR case returns true when it shouldn't.
You also repeat yourself too much. It's annoying to write, and if there is an error, like you have, it needs to be fixed in many places. Use DRY (Don't Repeat Yourself) and create a function that tells you if you have a vowel or not.
Then, you only need to explicitly check for just the YES cases or just the NO cases. Here's an example:
#include <iostream>
#include <string>
bool is_vowel(char c) {
std::string vowels = "aeiou";
return vowels.find(c) != std::string::npos;
}
int main() {
char first;
char second;
std::cout << "Letter: ";
std::cin >> first;
std::cout << "Letter: ";
std::cin >> second;
bool firstIsVowel = is_vowel(first);
bool secondIsVowel = is_vowel(second);
if ((firstIsVowel && secondIsVowel) || (!firstIsVowel && !secondIsVowel)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
Output:
~/tmp
❯ ./a.out
Letter: a
Letter: i
YES
~/tmp
❯ ./a.out
Letter: b
Letter: c
YES
~/tmp
❯ ./a.out
Letter: a
Letter: h
NO
~/tmp took 4s
❯ ./a.out
Letter: h
Letter: a
NO
I have managed to make it work. Thank you guys!
#include <iostream>
using namespace std;
int main()
{
char a = 'a';
char b = 'b';
bool vowel1, vowel2;
cout << "enter first letter: " << endl;
cin >> a;
cout << "enter second letter: " << endl;
cin >> b;
vowel1 = (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u');
vowel2 = (b == 'a' || b == 'e' || b == 'i' || b == 'o' || b == 'u');
if ((vowel1 && vowel2) || (!vowel1 && !vowel2))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
if (vowel1)
{
cout << "vowel: " << a << endl;
}
else
{
cout << "consonant: " << a << endl;
}
if (vowel2)
{
cout << "vowel: " << b << endl;
}
else
{
cout << "consonant: " << b << endl;
}
return 0;
}
This code is replacing all the characters. Not just vowels. What am I doing wrong?
using namespace std;
bool isVowel(char);
int main() {
string fName = "";
string lName = "";
cout << "Enter first name: " << endl;
cin >> fName;
cout << "Enter last name: " << endl;
cin >> lName;
string name = fName + " " + lName;
cout << name << endl;
for(int i = 0; i < name.length(); i++) {
if(isVowel(name.at(i))) {
name[i] = 'z';
}
}
cout << name << endl;
}
bool isVowel(char c) {
if(c == 'a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'O' || 'E' || 'I' || 'U') {
return true;
}
else {
return false;
}
}
I did some research online and I think my problem lies in that I am passing the character as a reference? I didn't understand how that could be...
The isVowel() function checks if the char is a vowel I think that's where the problem lies, since the program is replacing all the characters I'm assuming that function is not working.
you need to put your if statement as (c == 'a' || c == 'e' || c == 'i'..., the way it is written currently it casts all of the characters on their own as boolean expressions.
I am working on a project right now and when I try to run what I have below it gives me an error that says "uninitialized local variable 'userOption' used" on line 22, while (isValidOption(userOption) == true) {.
How do I fix that error? Thank you.
#include<iostream>
#include <string>
using namespace std;
char toupper(char ch) {
if (ch >= 'A'&&ch <= 'Z')
return(ch);
else
return(ch - 32);
}
bool isValidOption(char ch) {
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X')
return(true);
else
return(false);
}
char getMainOption() {
string UserInput;
char userOption;
while (isValidOption(userOption) == true) {
cout << "Choose One of the following options\n";
cout << "I--List Our Inventory\n";
cout << "O--Make an Order\n";
cout << "L--List all Orders made\n";
cout << "X--Exit\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
if (!isValidOption(userOption)) {
cout << "Invalid String\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
}
if (userOption == 'I')
cout << "Listing Our Inventory\n";
else if (userOption == 'O')
cout << "Make an order\n";
else if (userOption == 'L')
cout << "Listing all orders\n";
}
return userOption;
}
int main() {
char choice;
choice = getMainOption();
system("pause");
return 0;
}
What the error is saying that you're trying to read from userOption before you've ever written to it. If a variable is uninitialized, its memory contents will be full of junk left behind by other functions and it can easily cause bugs. In your case, you'll want to read input from the user into userOption before you do any logic on it. This can be done with a do-while loop:
char userOption; // not yet initialized
do {
...
cin >> userOption; // userOption gets initialized here on first loop run
} while (isValidOption(userOption)); // no need for == true, that's a tautology :-)
// NOTE: perhaps you want to loop while the input is INvalid, as in
// while (!isValidOption(userOption)); ?
A couply code-review comments I would additionally give are:
std::toupper already exists in <cctype>. Docs are here
return is not a function call and it's better to write return ch; than return(ch);
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X'){ return true; } else { return false; } is completely equivalent to the shorter return ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X';
Also take a look at system(“pause”); - Why is it wrong?
Happy coding! Let me know if questions remain
Been given a task to change my code to dynamic array.
The program asks you to input array size 1 to 100. After that input vowels 1 by 1 with the normal array teikums[100]; it outputted the vowels and the vowel amount.
Been given a task to make dynamic array without the "new".
But after adding the dynamic array:
char *teikums = (char*)malloc(100);
It outputs blank space.
#pragma hdrstop
#pragma argsused
#include <string>
#include <tchar.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
int main() {
char *teikums = (char*)malloc(100);
int c, i, count, patsk; // Patskani
char yesno; // Atkartosanas Mainigais
do {
cout << " " << teikums[i];
system("cls"); // Notira Ekranu
do {
patsk = 0; // Pieskir vertibu
cout << "Input array size 1-100: ";
cin >> count;
if (count > 100 || count < 1) {
cout << "Array cant be lower or higher than 0\n";
}
} while (count > 100 || count < 1);
do {
cout << "Input " << count << "letters one by one\n";
for (i = 1; i <= count; i++) {
cin >> teikums[i];
if (!((teikums[i] >= 'a' && teikums[i] <= 'z') || (teikums[i] >=
'A' && teikums[i] <= 'Z'))) {
cout << "Error! Only input letters\n";
i = i - 1;
}
}
} while (i <= count);
cout << "\nUsed Vowels:";
for (i = 0; teikums[i] != '\0'; i = i + 2) {
if (teikums[i] == 'a' || teikums[i] == 'e' || teikums[i] == 'i' ||
teikums[i] == 'o' || teikums[i] == 'u' || teikums[i] == 'A' ||
teikums[i] == 'E' || teikums[i] == 'I' || teikums[i] == 'O' ||
teikums[i] == 'U') {
++patsk;
cout << " " << teikums[i];
teikums[i] = 0;
}
}
cout << "\nVowel ammount: " << patsk;
cout << ("\nDo you wish to continue(Y/Else):");
// prasa lietotajam vai velas atkartot
cin >> yesno;
if (yesno == 'y' || yesno == 'Y') {
}
else {
return 0;
}
} while (tolower(yesno) != 'n');
getch();
}
In this line:
cout << " " << teikums[i];
i is not initialized and therefore it contains an indeterminate value.
This is causing all your troubles. But there may be other problems elsewhere, I didn't check all details.
If it worked with char teikums[100]; it's pure coincidence.
Google "C undefined behaviour" for more information.
So I have this program below and currently after I run it outputs this:
abcdefghijklmnopqrstuvwxyz
eklpyqrbgjdwtcaxzsnifvhmou
TEst
iyniЉhb�{���{���`�5b�v4b�q4b�{����8b�`�5b��`{���{����o���7�vb��{�����or��o���#`�lhb���5b��`x#
any reason why?
also the lines which are meant to be randomised currently aren't random
#include <algorithm>
#include <array>
#include <iostream>
#include <numeric>
#include <fstream>
#include <string>
using namespace std;
int main()
{
char Text[256];
array<char, 26> letters;
iota(letters.begin(), letters.end(), 'a');
for(char c: letters) //Array before shuffling
{
cout << c;
}
cout << '\n';
random_shuffle(letters.begin(), letters.end());
for(char c: letters) //After shuffling
{
cout << c;
}
cout << '\n';
cin.getline (Text,256);
for (char & c : Text)
{
if (c == 'a' || c == 'A')
{
cout << letters[0];
}
else if (c == 'b' || c == 'B')
{
cout << letters[1];
}
else if (c == 'c' || c == 'C')
{
cout << letters[2];
}
else if (c == 'd' || c == 'D')
{
cout << letters[3];
}
else if (c == 'e' || c == 'E')
{
cout << letters[4];
}
else if (c == 'f' || c == 'F')
{
cout << letters[5];
}
else if (c == 'g' || c == 'G')
{
cout << letters[6];
}
else if (c == 'h' || c == 'H')
{
cout << letters[7];
}
else if (c == 'i' || c == 'I')
{
cout << letters[8];
}
else if (c == 'j' || c == 'J')
{
cout << letters[9];
}
else if (c == 'k' || c == 'K')
{
cout << letters[10];
}
else if (c == 'l' || c == 'L')
{
cout << letters[11];
}
else if (c == 'm' || c == 'M')
{
cout << letters[12];
}
else if (c == 'n' || c == 'N')
{
cout << letters[13];
}
else if (c == 'o' || c == 'O')
{
cout << letters[14];
}
else if (c == 'p' || c == 'P')
{
cout << letters[15];
}
else if (c == 'q' || c == 'Q')
{
cout << letters[16];
}
else if (c == 'r' || c == 'R')
{
cout << letters[17];
}
else if (c == 's' || c == 'S')
{
cout << letters[18];
}
else if (c == 't' || c == 'T')
{
cout << letters[19];
}
else if (c == 'u' || c == 'U')
{
cout << letters[20];
}
else if (c == 'v' || c == 'V')
{
cout << letters[21];
}
else if (c == 'w' || c == 'W')
{
cout << letters[22];
}
else if (c == 'x' || c == 'X')
{
cout << letters[23];
}
else if (c == 'y' || c == 'Y')
{
cout << letters[24];
}
else if (c == 'z' || c == 'Z')
{
cout << letters[25];
}
else if (c == ' ')
{
cout << ' ';
}
else if (c == '/n')
{
return 0;
}
else
{
cout << c;
}
}
}
else if (c == '/n')
{
return 0;
}
Should be
else if (c == '\n')
{
return 0;
}
However, if you're looking for the end of your input, you actually want
else if (c == '\0')
{
return 0;
}
Which is a null terminator which indicates the end of a string. Basically you're getting all the junk that is stored in the entire 256 character array.
However, that doesn't help with your 29 if else statements. Try this:
if(c == ' '){ // Space
cout << ' ';
}
else if(c >= 'A' && c <= 'Z'){ // Uppercase
cout << letters[c - 'A'];
}
else if(c >= 'a' && c <= 'z'){ // Lowercase
cout << letters[c - 'a'];
}
else if(c == '\0'){ // End of string
return 0;
}
else{ // Anything else
cout << c;
}
How it works:
There are not "letters" in a computer, only binary. 'A' doesn't exist, but 01000001 which is 65 which is A does. So if you enter an 'A', your program will see a 65. However, I just happen to know that in your letters array, you have an A in position 0, so letters[0] == letters['A' - 'A']. The same logic can be used for B, C, D, ect. The same thing for the lowercase letters, they just at a different range (97-122).
Problem is here
else if (c == '/n') // '/n' is not correct
change it to
else if (c == '\0') // Check EOF