C++ array with wrong input - c++

So I wrote this program to code to read in a number of ints, and then its supposed to read the array back to backwards. however, it just reads back all 0s
while (true)
{
cin >> input;
if (input == -1 && gotStuff == false) {return 0;}
else if (input == -1 && gotStuff == true) {break;}
else
{
inputData[pos1] = input;
pos1 ++;
gotStuff = true;
}
}
for (int i = pos1; i >= 0; i--)
{
outputData[pos2] = inputData[pos1];
pos2 ++;
cout << outputData[pos1] << " ";
}
Why is this reading back as all 0s?

You have a clear problem here
for (int i = pos1; i >= 0; i--)
{
outputData[pos2] = inputData[pos1];
pos2 ++;
cout << outputData[pos1] << " ";
}
because you always try to print outputData[pos1] but pos1 is never changed within your loop. Therefore you always output the same character. Similarly you are always copying the same character of inputData to the outputData array so when the loop exits, outputData will just contain the same character at different indices.
You might have better luck with the following loop which at least copies and prints the correct characters
pos2 = 0;
for (int i = pos1-1; i >= 0; i--)
{
outputData[pos2] = inputData[i];
cout << outputData[pos2] << " ";
pos2++;
}
You may have other problems with your code too as you do not show us in the question what the values of pos1 and pos2 have been initialised with.

When you loop through the array here:
for (int i = pos1; i >= 0; i--)
{
outputData[pos2] = inputData[pos1];
pos2 ++;
cout << outputData[pos1] << " ";
}
you are always accessing the same position: pos1 in your input data. If you change this loop to this
for (int i = pos1 - 1; i >= 0; i--)
{
outputData[pos2] = inputData[i];
pos2 ++;
cout << outputData[pos2 - 1] << " ";
}
it will count down like you intended it to. That is because i is decremented with every iteration of the loop, while pos1 is not. It was probably reading all 0s because inputData[pos1] was 0.

Related

C++ Comparing strings to determine palindrome

I am trying to determine if a string is a palindrome by reversing the string and then comparing the letters of both strings. The code is provided underneath. So far whatever I put I always get "is a palindrome " as an output. I am aware of the short cut method for doing this easily and efficiently but trying to understand the long way as well. I am using C++ 11
#include <iostream>
#include <string>
using namespace std;
string reversed = " ";
void reverse_sentence(string s)
{
for (int i = 0; i <= s.length(); i++)
{
reversed = s[i] + reversed;
}
cout << reversed;
}
void is_pal(string reversed, string s)
{
int flag = 0;
// if(s == string(s.rbegin(), s.rend())){
// cout << "is a palindrome"<<endl;
// }else{
// cout <<"failed"<<endl;
// }
for (int i = 0; i <= s.length(); i++)
{
for (int j = 0; j <= reversed.length(); j++)
{
if (s[i] != reversed[j - 1])
{
flag = 1;
}
}
}
if (flag == 1)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}
int main()
{
string s = "hello";
reverse_sentence(s);
is_pal(s, reversed);
return 0;
}
First issue...
your for loops go out of bounds... length() gives you number of characters in the string. Those characters have index 0 through length() - 1. Because you are using <= s.length() however, then the last time through you get erroneous data, if it doesn't give you out of bounds error. For loops using length() should be from i = 0 to i < s.length()
Biggest issue...
void is_pal(string reversed, string s)
{
int flag = 0;
for (int i = 0; i <= s.length(); i++)
{
for (int j = 0; j <= reversed.length(); j++)
{
if (s[i] != reversed[j - 1])
{
flag = 1;
}
}
}
if (flag == 1)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}
Your j loop is inside of your i loop.. which means that s[i] never changes as you compare it to every single value in reversed... unless every single character in reversed is the same character... then one of them is guaranteed to be not equal to s[i] which means that flag will be set to 1... which means your function reports it to be a palindrome...
Not only that.. but you already went through the process of doing the reverse... why are you trying to compare against reverse.. in reverse order? That would be the same as comparing against the original string in normal order...
Assuming your reverse_sentence function works correctly... then s.length() is the same as reversed.length(). So to see if s is the same forwards as it is backwards then the letter at each index of s should be exactly the same as the letter at the same index in reversed. Also what you are looking for is when they don't match... so you should initialize your flag to assume at the beginning that they are going to be matching and only set it to false when you discover that they don't match...
void is_pal(string reversed, string s)
{
bool flag = true;
// run loop through length of s or until we know s doesn't match reversed
for (int i = 0; i < s.length() && flag; i++)
{
if (s[i] != reversed[i])
{
flag = false;
}
}
if (flag)
{
cout << "is palindrome" << endl;
}
else
{
cout << "not palindrome" << endl;
}
}

Can't get output right, need same code on different line

Hey so my code works but I need to get this output right, I need it to output the letters I put in 2 times. It will print it once correctly but I added a loop and it bunches the Chars together instead of printing it 2 times in the loop. If I separate it with endl or \n it will separate the chars. I just want it to print the whole line I enter 2 times
{
char c;
string s;
int index = 0;
cout << "Enter a line:";
cin.get(c);
while (c != '\n' && index < size) {
x[index] = c;
cin.get(c);
index++;
}
Letter = index;
cout << "" << Letter << endl;
int k = 0;
for (int i = 0; i < Letter; ++i)
{
bool found = false;
for (int j = 0; j < k; ++j)
if (x[i] == x[j])
found = true;
if (!found)
x[k++] = x[i];
s = +x[i];
for (int z = 0; z < 1; z++) {
cout << "" << s;
}
}
Letter = k;
}
To read a line and print it twice:
std::string line;
if (std::cin.getline(line))
{
std::cout << line << '\n' << line << '\n';
}

C++ String subcript out of range issue

I'm a student currently studying C++ and I have a problem with a code that I am trying to create. The code I am supposed to create is meant to find the hamming distance of 2 words that the user will input. (For e.g "Ironman" and "Iron" hamming distance is "3")
However, I ran into an error when I tried compiling and I can't seem to find out what the problem is. The error of "String subscript out of range" keeps popping up if the first input is longer than the second input.(It only fails to work when I try to input "Spiderman Ironman". Shorter words such as "Sean Sea" works fine.) If the second input is longer than the first input, OR if both the inputs are the same length, the entire code works fine.
string str1;
string str2;
cout << "Question 1" << endl;
cout << "Input two words (separated by space or enter) : ";
cin >> str1;
cin >> str2;
int count = hamming_distance(str1, str2);
cout << "> Hamming distance between \"" << str1 << "\" and \"" << str2 << "\" is " << count << endl;
int i;
int firstLength = str1.length();
int secondLength = str1.length();
int thirdLength;
int counter = 0;
//if the longest word is first string (Where the issue is causing)
if (firstLength > secondLength)
{
thirdLength = firstLength - secondLength;
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if the longest word is second string
else if (secondLength > firstLength)
{
thirdLength = secondLength - firstLength;
for (i = 0; i < secondLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
for (i = 0; i < thirdLength; i++)
{
counter++;
}
}
//if both words have the same length
else if (firstLength == secondLength)
{
for (i = 0; i < firstLength; i++)
{
if (str1[i] != str2[i])
{
counter++;
}
}
}
return counter;
It would be greatly appreciated if y'all could help me find out what the actual problem is with my code. Thank you!
You need to initialise your variables correctly:
int firstLength = str1.length();
int secondLength = str2.length();
You're also determining that one string is bigger than another, then proceeding to access elements in the shorter string according to the length of the longer one, which is giving you the subscript out of range error. You need to revise the tests when firstLength > secondLength and vice versa.

Bulls & Cows project: cow checking

I'm almost done with my Bulls and Cows project however if I enter a word or a sequence of numbers with an alphabet or number repeating, the 'cow' portion of the code messes up. As an example: consider the following
Enter something that you want someone to guess: cool
Time to guess! The code is of size 4. book
COWS: 0 BULLS: 2
ozzo
COWS: 4 BULLS: 0
As you can see, after entering "ozzo", the cow value should be 2, not 4.
How can I fix this without having to change the entire code?
for (size_t i = 0; i != startg.getSize(); ++i){
if (guess[i] == origWord[i]){
bullCtr++;
} else {
for (size_t j = 0; j != startg.getSize(); ++j){
if (origWord[i] == guess[j]){
cowCtr++;
}
}
}
}
Code after applying fix:
for (size_t i = 0; i != startg.getSize(); ++i){
if (guess[i] == origWord[i]){
bullCtr++;
} else {
for (size_t j = 0; j != startg.getSize(); ++j){
if (origWord[i] == guess[j]){
origWord[i] = 'X';
cowCtr++;
}
}
}
origWord = origWordcpy;
}
Your cow checking is problematic.
What I would do for the sake of ease (not exactly) is this (I'm talking about the else statement only):
for(unsigned int j = 0 ; j != startg.getSize() ; j++)
{
if(origWord[i] == guess[j])
{
origWord[i] = 1; //Just assigning a certain value there to mark that we've already did something with it
cowCtr++;
}
}
And that should do the work.
EDIT:
You should obviously have a temporary string instead of origWord because changing it would affect the next iteration of the outer loop (getting the guess and comparing again) - I only showed you the way.
Here is one possible implementation of the Bulls & Cows game:
// used constants; numbers to be guessed
const int first_num = 2;
const int second_num = 4;
const int third_num = 1;
const int forth_num = 5;
int main(){
// vector holding the values to be guessed
vector<int>gamenum(4);
gamenum[0] = first_num;
gamenum[1] = second_num;
gamenum[2] = third_num;
gamenum[3] = forth_num;
// prompt message; input cycle till perfect guess (4 bulls)
int bulls = 0;
while (!(bulls == 4)){
// vector holding the guesses
vector<int>guesses;
// vector input values
int guess1(0), guess2(0), guess3(0), guess4(0);
cout << "\t\tPlay the game ""Bulls and Cows\n""" << endl;
cout << "Enter a set of four numbers, separated by whitespace space: ";
cin >> guess1 >> guess2 >> guess3 >> guess4;
guesses.push_back(guess1);
guesses.push_back(guess2);
guesses.push_back(guess3);
guesses.push_back(guess4);
// input confirmation; show your guess
cout << "\nYour guess is: ";
for (int i = 0; i < guesses.size(); ++i){
cout << guesses[i];
}
// bulls criterion
for (int j = 0; j < guesses.size(); ++j){
if (guesses[j] == gamenum[j]) ++bulls;
}
// cows criterion
int cows = 0;
for (int gue = 0; gue < guesses.size(); ++gue){
for (int gam = 0; gam < gamenum.size(); ++gam){
if (guesses[gue] == gamenum[gam] && gue != gam) ++cows;
}
}
// print result
if (bulls < 4){
cout << "\nBulls: " << bulls << " and Cows: " << cows <<endl;
cout << "\n\n\n" << endl;
// reset bulls
bulls = 0;
}
// empty guesses vector
guesses.clear();
// reset cows
cows = 0;
}
// print success
cout << "\nPerfect Guess!" << endl;
cout << "Bulls: " << bulls << endl;
cout << "\n\n\n" << endl;
keep_window_open();
return 0;
}
Not optimal by any means, rudimentary, but working. You can use it as benchmark.

Why do i get a segmentation fault when I try to enter "x" to exit my program

the function DataDisplayAndSearch for some reason causes a segmentation fault when i enter "x" to exit the program. I have tried debugging and cannot figure out what the problem could be. This is homework
string DataDisplayAndSearch (int customerCount, string ssn[])
{
//local variables
int index;
int count;
int numberLen;
int numberLocation = NOT_FOUND;
int high;
int low;
int middle;
bool invalidNumber = false;
string choice;
cout << " Social Security Numbers on file are:" << endl;
for (index = 0; index < customerCount; index++)
{
cout << " " << ssn[index] << " ";
}
do
{
cout << endl << endl << " Enter SSN to find (or X to exit):";
invalidNumber = false;
cin >> choice;
if (choice != EXIT && choice != EXIT1)
{
numberLen = choice.length();
if (numberLen < LENGTH || numberLen > LENGTH)
{
invalidNumber = true;
}
for (count = 0; count < LENGTH; count++)
{
if (isprint(choice[count]));
else
{
invalidNumber = true;
}
}
if (choice[IDX2] != DASH || choice[IDX5] != DASH)
{
invalidNumber = true;
}
low = 0;
high = customerCount - 1;
while ((low <= high) && (numberLocation == NOT_FOUND))
{
middle = (low + high) / 2;
if (choice > ssn[middle])
{
high = middle - 1;
}
else if (choice < ssn[middle])
{
low = middle + 1;
}
else
{
numberLocation = middle;
}
}
if (numberLocation == NOT_FOUND)
{
cout << " Error!! Please enter a valid SSN." << endl;
}
if (invalidNumber)
{
cout << " Input dashes and digits " << choice << " are formatted."
<< " SSN must be exactly 11 characters long, formatted as:"
<< " ###-##-###" << endl;
}
} //end of if
} while (((invalidNumber) && (choice != EXIT && choice != EXIT1 ) && (numberLocation == NOT_FOUND)));
}
When the outer loop exits for any reason, including choice == EXIT, the function exits without providing a return value of type string. The caller then attempts to use a non-existent string object, hence the crash.
Crossing the closing brace of a function with a non-void return type is undefined behavior. It may crash, but might not crash every time. Your compiler might warn you about things like this if you can enable its warning feature, such as by -Wall on the command line.