C++ Debug Assertion Failed string arrays - c++

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);

Related

How do you insert characters into middle of string? C++

The purpose of this code is to insert an x in between repeating letters. For example, if I were to input "CoolBoolFallmoose", the output would be "CoxolBoxolFalxlmoxose".
The code is also supposed to make an even number of pairs of letters, so if there is an odd amount of characters, an x is added to the end of the string. An example for this would be if we had "ball", it would become "balxlx" to make even pairs: "ba" "lx" "lx".
This is the code I have so far:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string cipher, plain, paired = "";
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
for (int i=0;i<plain.length();i++){
if (plain[i]==plain[i+1]){
plain.insert(i,'x');
}
paired[i]=paired[i];
cout<<paired[i];
}
if (paired.length() % 2!= 0){
paired=+'x';
}
cout<<paired<<endl;
return 0;
}
The output I get is just the same as my input, no "x" added in any place.
The issue I am having is, every time I try to use the append() or insert() function for strings, I get an error from my compiler, which is xCode. Is there another way to solve this code?
EDIT: The error says:
No matching member function to call for insert
It also comes up for append().
I don't really know what you wanted to do with this part:
paired[i]=paired[i];
cout<<paired[i];
but otherwise the logic is good. Here is my take on it, x is a counter:
#include <iostream>
#include <string>
using namespace std;
int main(){
string m,n;
int x = 0;
cout << "Input: " << endl;
getline(cin, m);
for(int i = 0;i < m.length();i++){
x++;
n = n + m[i];
if(m[i] == m[i+1]){
n = n + 'x';
x++;
}
}
if((x % 2) != 0){
n = n + 'x';
}
cout << n;
return 0;
}
If you look at the available overloads of std::string::insert(), you will see that your statement plain.insert(i,'x'); does not match any of them, hence the compiler error. The overloads that takes a single char require either:
an index and a count (you are omitting the count)
an iterator and an optional count
There is, however, a couple of overloads that take just an index and a value, but they require a const char* or a std::string, not a single char.
Also, paired[i]=paired[i]; is a no-op. Except in your case, since paired has a size() of 0 since you never append anything to paired, so actually any access to paired[...] is undefined behavior.
Try this instead:
#include <iostream>
#include <string>
using namespace std;
int main(){
string plain, paired;
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
paired = plain;
for (string::size_type i = 1; i < paired.size(); ++i){
if (paired[i] == paired[i-1]){
paired.insert(i, 1, 'x');
// or: paired.insert(paired.begin()+i, 'x');
// or: paired.insert(i, "x");
// or: paired.insert(i, string{'x'});
// or: paired.insert(paired.begin()+i, {'x'});
++i; // skip the x just inserted
}
}
if (paired.size() % 2 != 0){
paired += 'x';
}
cout << paired << endl;
return 0;
}
Demo
A couple of points
First, Although the string.insert function says it takes an int as its first argument it really wants an iterator in this case.
Second, you are inserting elements into your "plain" string which increases its length and you have plain.length within your loop so you create an infinite loop.
Third, insert inserts BEFORE the index so you need to add 1 to I.
The code below will work for your loop:
Int len = plain.length();
Int count = 0;
for (int i = 0; i < len + count; i++)
{
If (plain[i] == plain[i + 1])
{
plain.insert(plain.begin() + (i +1), 'X');
++count;
}
}
cout << plain;
And as, mentioned below, if you want to handle spaces you can use getline(cin, plain) instead of cin.

Convert userInput (string) to UserInput(int) mid for loop

I am working on a program that has to do with arrays. I decided that the input the user provides to be a string to later being converted to an integer once it is determined it is one. This way the program wouldn't run into an error when words/letters are entered. The issue I am having is the conversion from string to int. I want to change that because later in the program I am going to search the array for a given value and display it and its placement in the array. This is the code I have thus far:
#include <stdio.h>
#include <iostream>
using namespace std;
//check if number or string
bool check_number(string str) {
for (int i = 0; i < str.length(); i++)
if (isdigit(str[i]) == false)
return false;
return true;
}
int main()
{
const int size = 9 ;
int x, UserInput[size], findMe;
string userInput[size];
cout << "Enter "<< size <<" numbers: ";
for (int x =0; x < size; x++)
{
cin >> userInput[x];
if (check_number(userInput[x]))
{//the string is an int
}
else
{//the string is not an int
cout<<userInput[x]<< " is a string." << "Please enter a number: ";
cin >> userInput[x];}
}
int i;
for (int i =0; i < size; i++)
{
int UserInput[x] = std::stoi(userInput[x]); // error occurs here
}
for (int x= 0; x< size; x++)
{
if (UserInput = findMe)
{
cout <<"The number "<< UserInput[x] << "was found at " << x << "\n";
}
else
{
//want code to continue if the number the user is looking for isn't what is found
}
}
return 0;
}
Made comments here and there to kinda layout what I want the code to do and whatnot. I apperciate any help you can give, thank you.
This code:
int UserInput[x] = std::stoi(userInput[x]);
declares an int array of size x, to which you are assigning a single int (the result of std::stoi), which obviously doesn't work.
You need to assign an int to a particular index of the existing array, like this:
UserInput[x] = std::stoi(userInput[x]);
Given this comparison if (UserInput = findMe), which should actually be if (UserInput == findMe), it seems you want to declare a single int which stores the result of std::stoi. In that case, you should use a different name than the array, and write something like this:
int SingleUserInput = std::stoi(userInput[x]);
Also, please indent your code consistently, and compile with all your warnings turned on. Your code will be easier to read, and the compiler will point out additional problems with your code. And please don't use using namespace std;, it's a bad habit.
I don't understand why do u even need to use another loop to convert the string value to int. stdio.h header file does provides with preinstalled functions to make your work easier...
for (int x =0; x < size; x++)
{
getline(cin,userInput1[x]);
UserInput[x]=stoi(userInput1[x]);
}
stoi() function converts the string input to int, and you can call it dynamically as soon as you enter your string input,It will make you work easier and reduce the time complexity

C++ argument of type * is incompatible with parameter of type **

Hello I'm new to c++ and can't figure out why my code is doing this. I've scoured across the internet and can't find the solution I need. I appreciate all the help. The line that's giving me the problem is when I'm calling the function. According to visual studios it states that "argument of type 'char*' is incompatible with parameter of type 'char**'". It's referring to newArr.
#include <iostream>
#include <string>
#include <stdio.h>
#include <ctype.h>
#include "stdafx.h"
using namespace std;
bool isPalindrome(char *newArr[], int);
//int i = 0;
//char phrase;
//char c;
bool palindrome;
bool tOf;
int numb;
char c;
const int length = 80; //const so that it can't be changed
char inarr[length]; //array set to a const length of 80
char newArr[length]; //array that will have no spaces
string str;
int main()
{
cout << "This program tests if a word/phrase is palindrome.\n\n";
cout << "Please enter your phrase (just letters and blanks,
please):\n\n";
cin.getline(inarr, length);
//cout << array; //spits out the array
str = inarr; //turn into string
numb = str.length();
//cout << numb << "\n"; //how many characters in array
for (int i = 0; i < (numb / 2) + 1; i++)
{
for (int j = 0; j < (numb / 2) + 1; j++)
{
newArr[j] = inarr[i]; //from old array to new array
c = newArr[j];
newArr[j] = toupper(c); //change to all upper case
//cout << newArr[j];
i += 2; //goes to every other index to skip space in string
}
}
tOf = isPalindrome(newArr, numb); //calling of function
if (tOf == true) //the response to true or false
{
cout << "\nYes, the phrase is a palindrome!";
}
else
{
cout << "\nNo, the phrase is not a palindrome!";
}
return 0;
}
bool isPalindrome(char *newArr[], int numb) //function to determine true or
false
{
for (int i = 0; i < (numb / 2) + 1; i++) //within the array...
{
if (newArr[i] != newArr[(numb / 2) - i]) //if first index != last
and etc (iterates)
{
palindrome = false;
}
else
{
palindrome = true;
}
}
return palindrome;
}
You're trying to pass newArr (a char *) into isPalindrome() (which takes a char **). This is what "argument of type 'char*' is incompatible with parameter of type 'char**'" means.
To fix this, simply pass in a char **; you can do this by passing in the address of newArr instead of newArr itself:
tOf = isPalindrome(&newArr, numb); //calling of function
Brief
Change the function signature (both definition and declaration) of the function to
bool isPalindrome(char* newArr, int numb);
Call it
tOf = isPalindrome(newArr, numb);
Detail
If you call isPalindrome(newArr, numb). you are passing address of the first element either &newArr[0] . So you are function defination should be able to pick the address of the element. hence *newArr
Further your function will validate the details by using array arithmetic. which is all right .
Output
$ ./a.out
This program tests if a word/phrase is palindrome.
Please enter your phrase (just letters and blanks, please):
Palindrome
No, the phrase is not a palindrome!
$ ./a.out
This program tests if a word/phrase is palindrome.
Please enter your phrase (just letters and blanks, please):
YeseY
Yes, the phrase is a palindrome!
$

I'm having trouble with my conversion program

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.

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.