I'm having trouble with my conversion program - c++

For my class, I am to write a program in C++ that converts each character in a sentence to the opposite case (upper to lower, lower to upper). We are supposed to use arrays and a user-defined method, and this is what I came up with:
#include <iostream>
using namespace std;
// declare variables
int count = 0; // array counter
int i = 0; // loop control
char ch[100]; // each character entered will be stored in this array
char newCh[100]; // this will hold each character after its case has been changed
main()
{
cout << "Enter a sentence." << endl; // prompts user
while ( ch[count] != '\n' ) // loop continues until "enter" is pressed
{
cin >> ch[count]; // store each character in an array
count += 1; // increment counter
}
int convert(); // call user-defined function
}
// even though it isn't necessary, we are using a user-defined function to perform the conversion
int convert()
{
for ( i = 0; i >= 0; i++ )
{
if ( (ch[i] > 64) and (ch[i] < 91)
)
{
newCh[i] = tolower(ch[i]);
}
else
{
newCh[i] = toupper(ch[i]);
}
cout << newCh[i];
}
}
I'm not sure why, but it doesn't work. I don't believe that my while loop is terminating and executing the rest of the program. Any advice would be greatly appreciated.

The loop condition in while ( ch[count] != '\n' ) is wrong, as all entries in ch will be initialized to zero by the compiler, and as you increase count inside the loop the condition will never be false and you have an infinite loop, causing you to write beyond the limits of the array.
And writing beyond the limits of an array leads to undefined behavior, and will cause your whole program to be illegal.
I suggest you learn about std::string and std::getline.

There's a problem with your for loop - you want for ( i = 0; i < count; i++ ). Also your function can be void and you need to pass the count value into it (and you just need to invoke it with convert() without int or void in front.

I have rewrite your code with some modification. The following code works perfectly in my machine -
#include <iostream>
#include<cstdio>
#include<string>
using namespace std;
void convert(char *, int);
string line;
char input[1024];
char output[1024];
main()
{
cout << "Enter a sentence." << endl;
while (getline(cin, line)) { // POINT 1
cout<< line<<endl;
//converting to char array since you need char array
//POINT 2
for(int i=0; i< line.length(); i++){
input[i]=line[i];
}
convert(input, line.length());
cout<<output<<endl;
input[1024] = {0}; //POINT 3
output[1024] = {0};
}
}
//Custom Convert Method
void convert(char input[], int size){
for(int i = 0; i < size; i++){
if(input[i] >= 'a' && input[i] <= 'z'){
output[i] = toupper(input[i]);
} else {
output[i] = tolower(input[i]);
}
}
}
Note some points (in my comment) here -
POINT 1: reading a n entire line using getline() method. Here line is a string
POINT 2: since you need char array here I am converting the string line to char array input[1024]
POINT 3: input and output array are being reset to work with the next value;
Output of the code:
"Ctrl+C" will terminate the program
Hope it will help you.
Thanks a lot.

Related

Reversing string using stack (static array) in c++

i am new to this concept in c++
i am trying to reverse string using stack static array implementation in c++.
Input: qwerty
expected output: ytrewq
output which i am getting is: trewq
Can some one explain me why is this happening and any possible solution.
Here's my code
#include <iostream>
#include <string>
using namespace std;
#define SIZE 10
string arr[SIZE];
unsigned a = -1;
void push(char ch) {
a = a + 1;
arr[a] = ch;
}
void pop() {
a = a - 1;
}
void display() {
for (int j = a; j >= 0; j--)
cout << arr[j];
}
int main() {
string str;
getline(cin, str);
for (int i = 0; i < (str.length() - 1); i++)
push(str[i]);
display();
}
Remove the "-1" in :
for(int i=0;i<(str.length())-1;i++)
Else your array doesn't contains the last character.
I made the test without the -1, it works well.
The condition "< str.length()" is enough to loop on all string caracter.
In similar case, use the debugger to see what contains your variable. In these case the variable "arr" don't contains the last input caracter.
You push everything on the stack, so the last element can be popped first. Then do popping to fill a reversed strng. The stack should be a char array.
As this is typically a task, the rest is your puzzle.
Pop typically gives you the top element as:
char pop() {
char ch = arr[a];
--a;
return ch;
}
The correct way to reverse a string would be to do:
std::reverse(str.begin(), str.end());
But I think this might be homework/study so look at your output. You are just missing the last letter. That suggests the upper limit of your loop is wrong doesn't it?

How to properly compare strings in c++?

Good night to everyone!
I am trying to compare 2 strings in c++, using the .compare() function. However, the result i see is not what is expected from this function. Take a look please.
#include <iostream>
#include <string>
using namespace std;
class game
{
private:
char mtx [2][2];
int i = 0, j = 0, a = 0;
std::string matrix1;
std::string xis = "xx";
public:
game();
char winner();
};
game::game()
{
for(i = 0; i<2; i++)
{
for (j = 0; j<2; j++)
{
mtx [i][j] = 'x';
}
}
char game::winner()
{
i = j = 0;
for (j=0; j<2; j++)
{
matrix1 = mtx [0][j]; //string recieve the first line of the matrix.
}
a = xis.compare(matrix1);
cout << a<<endl;
}
int main(void) {
velha game;
velha.winner;
}
When I compile the program the a value printed is neither a '0' nor any other integers. It prints #85.
Notes: I've also tried to use <string.h> and strncmp() using a char array instead of std:: string but with no success.
I was trying to create a game class and I did not put here the other methods because they are not relevant). (also, I use Linux Mint to code)
Can anyone help me please in this context?
#include <iostream>
#include <string>
int main(void) {
std::string first, second;
std::cout << "First String: ";
getline(std::cin, first);
std::cout << "Second Line: ";
getline(std::cin, second);
if (first == second)
std::cout << "Same strings.";
else
std::cout << "Different strings.";
return 0;
}
Explanation: Just taken two strings from the user and matches straightforward without using any much complexity, just used a conditional operation.
For string compare and even strcmp the value returned will be the lexicographical comparison of the two strings. The following are the values you should see:
negative if *this appears before the character sequence specified by the argument in lexicographical order
0 if *this and the character sequence specified are equivalent
positive if *this appears after the character sequence specified by the argument in lexicographical order
If you are looking to get the first column of your matrix, do a string comparison on, you would want to do something like:
for(int col = 0; col < 2; col++) {
matrix1.push_back(mtx[0][col]); // This appends that character to the end of your string
}
If you are looking to get the rows you can just do the following:
matrix1 = mtx[0];
// To ensure you have a null terminated string
// Otherwise you will have garbage.
matrix1.replace(matrix1.begin() + 2, matrix1.end(), 1, "\0");
I have ran through the test with comparing that the matrix contains "xx" and ended up receiving 0. However a much easier comparison is to us operator == to simply return a true or false value.

C++ Debug Assertion Failed string arrays

I am coding an assignment for my class where a user will input 10 letter answers, and the program will return a grade. I recently changed my char arrays to string arrays, because I think it makes it easier to read.
I went to debug my code and am now getting the error "Deubug Assertion Failed." I do not know what this means or how to fix it.
Any help would be appreciated.
Thanks!
Below is my code:
// Lab 8
// programmed by Elijah Barron
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
//Function headers
string inputAnswers(string given);
int numCorrect(string correctAnswers, string given);
int main()
{
string correctAnswers = "BCADBADCAB";
string given;
int numRight = 0;
inputAnswers(given);
numCorrect(correctAnswers, given);
double grade = 10 * numRight;
cout << "Your quiz grade is " << grade << "%" << endl;
return 0;
}
//Get the answers
string inputAnswers(string given)
{
for (int n = 0; n < 10; n++)
{
cout << "Please enter your answer for question #" << n + 1 << " ";
cin >> given[n];
}
return given;
}
//Find if answers are correct or incorrect
int numCorrect(string correctAnswers, string given)
{
int numRight = 10;
int n = 0;
for (int n = 0; n < 10; n++);
{
if (given[n] != correctAnswers[n])
numRight -= 1;
}
return numRight;
}
The immediate issue is that given will start off as an empty string as you haven't assigned it a value:
cin >> given[n];
is causing the assert failure because you're trying to change the first (second, third etc) character in a string with a length of zero. To fix the assert problem (but not the program, which will always return 0%), just initialise the string:
string given = "ZZZZZZZZZZ";
To fix the rest of the stuff (btw this isn't the only way):
Change:
string inputAnswers(string given); //for both prototype and function.
to:
void inputAnswers(string& given); //pass by reference instead of pass by value.
//also get rid of "return given;"
Change:
int n = 0; //the n here is different to the one in the next line
for (int n = 0; n < 10; n++); //this n's scope begins and ends here thanks to the semicolon
{//the code here is executed once, this isn't in the loop!
if (given[n] != correctAnswers[n]) //we're using the first n here, which is 0.
numRight -= 1;
}
to:
for (int n = 0; n < 10; n++) //only one n variable and no semicolon
{// now this is in the loop and will execute 10 times.
if (given[n] != correctAnswers[n])
numRight -= 1;
}
Don't bother with this line:
int numRight = 0; //Set at 0 and then never changed.
and change:
numCorrect(correctAnswers, given);
to:
int numRight = numCorrect(correctAnswers, given); //declared when necessary and assigned the correct value
You either want to reserve enough space in your vector to hold 10 characters, or use push_back to populate the vector. Indexing a vector with [] won't grow the vector for you.
EDIT:
Ignore the first part about reserve. That doesn't stop the debug assertion. You will want to change this
cin >> given[n];
To something like this:
char input;
cin >> input;
given.push_back(input);

c++ palindrome program using array

I am having a problem with my palindrome program. I am required to use arrays and show how a push and pop would work without .push or .pop. The trouble I am having is when I enter a 3 letter word it will say yes it is a palindrome but if I enter a word that is 4 or more characters it will say not a palindrome even if it is. ex. kayak. Dont see where I am going wrong.
#include <iostream>
#include <string>
using namespace std;
int main()
{
char original[13];
int stkptr=-1;
int x = strlen(original)-1;
cout <<"Enter a character"<<endl;
for( ++stkptr ; stkptr<13;stkptr++)
//store user input into the array
{
cin>>original[stkptr];
if(original[stkptr]=='0')
break;
cout<<original[stkptr]<<" Stack pointer is: "<<stkptr<<endl;
}
//POP
for (--stkptr; stkptr>=0;stkptr--)
cout<<original[stkptr]<<" Stack pointer is: "<<stkptr<<endl;
for(int i = 0; i <= x; i++)
{
if (original[i] == original[x-i])
{
continue;
}
else
{
cout<<"\nNot a palidrome\n"<<endl;
system("pause");
return 0;
}
}
cout << "\nIndeed Palidrome\n"<<endl;
system("pause");
return 0;
}
Though you overly complicated the logic, I will tell what is wrong the current code.
you are going wrong with x. You initialize it to string length when there is no "string" (Also, your char array should have a \0 at the end for strlen() to work). Assign stkptr-1 to x before pop and remove pop.
And in your loop you should iterate only till half of the array, since you are comparing char-by-char from begin and end
for(int i = 0; i <= x/2; i++)
bool checkIsPalindrome(string s){
int nLength = s.length();
string s1, s2;
if(nLength & 1) // is Odd
nLength--;
nLength = nLength/2;
//take the first half
s1 = s.substr(0,nLength);
//pop off the last half of characters into the string
for(int i = s.length()-1; i > nLength; i--)
s2+= s.at(i);
if(s1 == s2)
return true;
else
return false;
}

Error-correcting loop in C++, find specific chars in a string and flag as bad input

Here is v1.0 of the binary_to_decimal converter I wrote. I want to make several changes as I keep improving the spec. Classes and pointers will be added as well in the future. Just to keep me fresh and well practiced.
Well, I now want to implement an error-correcting loop that will flag any character that is not a 0 or a 1 and ask for input again.
I have been trying something along the line of this code block that worked with an array.
It might be way off but I think I can tweak it. I am still learning 0_0
I want to add something like this:
while ((cin >> strint).get())
{
cin.clear(); //reset the input
while (cin.get() != '\n') //clear all the way to the newline char
continue; //
cout << "Enter zeroes and/or ones only! \n";
}
Here is the final code without the error-correcting loop:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
const int MAX = 100;
int conv(int z[MAX], int l[MAX], int a);
int main()
{
int zelda[MAX];
int link[MAX];
string strint;
int am;
cout << "Enter a binary number: \n";
(cin >> strint).get(); //add error-correction to only read 0s and 1s.
am = strint.size();
cout << am << " digits entered." << endl;
int i = 0;
int p = 0;
while (i < am)
{
zelda[i] = strint[p] - '0'; //copies the string array elements into the int array; essentially STRING TO INT (the minus FORCES a conversion because it is arithmetic) <---- EXTREMELY CLEVER!
++i;
++p;
}
cout << conv(zelda, link, am);
cin.get();
return 0;
}
int conv(int zelda[MAX], int link[MAX], int length)
{
int sum = 0;
for (int t = 0; t < length; t++)
{
long int h, i;
for (int h = length - 1, i = 0; h >= 0; --h, ++i)
if (zelda[t] == 1)
link[h] = pow(2.0, i);
else
link[h] = 0;
sum += link[t];
}
return sum;
}
thanks guys.
I'm not completely sure of what you're trying to do, but I think what you're wanting is string::find_first_not_of. There's an example included in that link. You could have something like: myString.find_first_not_of("01");
If the return value is string::npos, then there are no characters in the string other than 1 or 0, therefore it's valid. If the return value is anything else, then prompt again for valid input and continue looping until the input's valid.