Hackerrank "Abort Called": I don't know what's wrong[C++] - c++

I was solving a problem from hackerrank in VSCode. I thought I had finally figured out the solution, so I copied it over to the hackerrank compiler. I hit compile and it pops up an "Abort Called" error. Here's the code:
#include <iostream>
#include <bits/stdc++.h>
void printEvenArray(char charArray[], int length)
{
for(int i = 0; i < length; i++)
{
if(i == 0 || i % 2 == 0)
{
std::cout << charArray[b];
}
}
std::cout << ' ';
}
void printOddArray(char charArray[], int length)
{
for(int i = 0; i < length; i++)
{
if(i != 0 && i % 2 != 0)
{
std::cout << charArray[i];
}
}
std::cout << '\n';
}
int main() {
int numOfSubjects, stringLength = 0;
std::cin >> numOfSubjects;
std::string subjectString[numOfSubjects];
char stringToCharArray[stringLength + 1];
for(int i = 0; i < numOfSubjects; i++)
{
std::cin >> subjectString[i];
}
for(int x = 0; x < numOfSubjects; x++)
{
stringLength = subjectString[x].length();
strcpy(stringToCharArray, subjectString[x].c_str());
printEvenArray(stringToCharArray, stringLength);
printOddArray(stringToCharArray, stringLength);
}
return 0;
}
This code compiles fine in VSCode. It gives me the desired outcome, but as soon as I bring it over to hackerrank, it gives an "Abort Called" error. I've read up online that abort called only shows up when either I try to use memory I don't have access to or is read only, or if I use a certain macro, am I'm not using any macros. I'm also relatively knew to C++, and clueless to memory management if that's what the issue is here. I appreciate any help a whole lot.

char stringToCharArray[stringLength + 1];
So, stringToCharArray has length 1. Nothing in the loop changes that. Your strcpy is much longer than one character, so it just overwrites whatever was next in memory. On one compiler you got away with this behavior, but the other (probably deliberately set to look for boundary violations like this) aborted.
Read about https://en.wikipedia.org/wiki/Buffer_overflow.
There are some other improvements you can make. For instance, i+=2 can step through a loop two at a time without checking whether i be odd or even.

Related

2d array comparing with char

I have an array that reads data from a file, the data is binary digits such as 010011001001 and many others so the data are strings which I read in to my 2d array but I am stuck on comparing each value of the array to 0. Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000][12];
int i = 0, zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while(!inFile.eof())
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 12; j++)
{
inFile >> myArr[i][j];
j++;
}
i++;
}
}
for(int j = 0; j < 12; j++)
{
for(int i = 0; i < 5000; i++)
{
if(myArr[i][j].compare("0") == 0)
{
zeroCount++;
}
else
{
oneCount++;
}
i++;
}
if(zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
j++;
}
}
some input from the text file:
010110011101
101100111000
100100000011
111000010001
001100010011
010000111100
Thank you for editing you question and providing more information. Now, we can help you. You have 2 major misunderstandings.
How does a for loop work?
What is a std::string in C++
Let us start with the for loop. You find an explanation in the CPP reference here. Or, you could look also at the tutorial shown here.
The for loop has basically 3 parts: for (part1; part2; part3). All are optional, you can use them, but no need to use them.
part1 is the init-statement. Here you can declare/define/initialize a variable. In your case it is int i = 0. You define a variable of data type int and initialize it with a value of 0
part2 is the condition. The loop will run, until the condition becomes false. The condition will be check at the beginning of the loop.
part3 is the so called iteration-expression. The term is a little bit misguiding. It is basically a statement that is executed at the end of the loop, before the next loop run will be executed and before the condition is checked again.
In Pseudo code it is something like this:
{
init-statement
while ( condition ) {
statement
iteration-expression ;
}
}
which means for the part of your code for(int j = 0; j < 12; j++)
{
int j = 0; // init-statement
while ( j < 12 ) { // while ( condition ) {
inFile >> myArr[i][j]; // Your loop statements
j++; // Your loop statements PROBLEM
j++; // iteration-expression from the for loop
}
}
And now you see the problem. You unfortunately increment 'j' twice. You do not need to do that. The last part3 of the for loop does this for you already.
So please delete the duplicated increment statements.
Next, the std::string
A string is, as its names says, a string of characters, or in the context of programming languages, an array of characters.
In C we used to write actually char[42] = "abc";. So using really a array of characters. The problem was always the fixed length of such a string. Here for example 42. In such an array you could store only 41 characters. If the string would be longer, then it could not work.
The inventors of C++ solved this problem. They created a dynamic character array, an array that can grow, if needed. They called this thing std::string. It does not have a predefined length. It will grow as needed.
Therefore, writing string myArr[5000][12]; shows that you did not fully understand this concept. You do not need [12], becuase the string can hold the 12 characters already. So, you can delete it. They characters will implicitely be there. And if you write inFile >> myString then the extractor operator >> will read characters from the stream until the next space and then store it in your myString variable, regardless how long the string is.
Please read this tutorial about strings.
That is a big advantage over the C-Style strings.
Then your code could look like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000];
int zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while (!inFile.eof())
{
for (int i = 0; i < 5000; i++)
{
inFile >> myArr[i];
}
}
for (int i = 0; i < 5000; i++)
{
zeroCount = 0; oneCount = 0;
for (int j = 0; j < 12; j++)
{
if (myArr[i][j]== '0')
{
zeroCount++;
}
else
{
oneCount++;
}
}
if (zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
}
}
But there is more. You use the magic number 5000 for your array of strings. This you do, because you think that 5000 is always big enough to hold all strings. But what, if not? If you have more than 5000 strings in your source file, then your code will crash.
Similar to the string problem for character arrays, we have also a array for any kind of data in C++, that can dynamically grow as needed. It is called std::vector and you can read about it here. A tutorial can be found here.
With that you can get rid of any C-Style array at all. But please continue to study the language C++ further and you will understand more and more.
Ther are more subtle problems in your code like while(!inFile.eof()), but this should be solved later.
I hope I could help

C++ delete duplicates from cstring [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a c-string that looks something like ABBBCACACACBA and I'm supposed to create a function that deletes the duplicate characters so I end up with ABC. I created a nested for loop that replaces every letter that matches the letter in the outer loop with a \0 and increments a counter that keeps track of the repeats. I'm getting -1 as the amount of repeats that should be documented, and from checking it spits out ABBC instead of ABC. I'm stumped, any ideas?
for (int i = 0; i < SIZE; i++)
{
for (int j = i + 1; j < SIZE; j++)
{
if (letter[i] == letter[j])
{
letter[j] = '\0';
repeatCounter++;
}
}
}
It is not enough to just replace duplicates with '\0', you have to actually remove them from the string and shift the remaining characters down. Try something more like this:
int size = SIZE, i = 0;
while (i < size)
{
int j = i + 1;
while (j < size)
{
if (letter[j] == letter[i])
{
for (int k = j + 1; k < size; k++)
{
letter[k-1] = letter[k];
}
letter[--size] = '\0';
repeatCounter++;
continue;
}
j++;
}
i++;
}
Live Demo
Here's a simple example which does what you want. It uses std::string to store the output. You can copy-n-paste the code here to test and run. Look into using std::string as it has functions which will make your life easy.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input("ABBBCACACACBA");
string output;
for(size_t i = 0; i < input.size(); i++)
{
if(output.find(input[i]) == string::npos)
{
output += input[i];
}
}
cout << "Input: " << input << endl;
cout << "Output: " << output << endl;
return 0;
}

VisualStudios throws exception while codeblocks does not [C++]

I have 2 questions:
Why does this work in codeblocks, but in visual studios throws an exception?
Can someone tell me what exactly this is doing: "if (text[i + j] == word[j]) {"
I spent hours trying to understand what it's trying to do but failed.
Source: https://github.com/Codecademy/learn-cpp/tree/master/8-references-and-pointers/bleep
Do I still need to point out I'm new to programming? Well I'm new so take it slow.
btw before looking at their solution I did find a way to do it using google I found the replace() function worked for me. But I still copied and pasted = no good. Their's is more natural without the use of others/inbuilt function(s).
main
#include <iostream>
#include <string>
#include "functions.h"
int main() {
std::string word = "broccoli";
std::string sentence = "I sometimes eat broccoli. The interesting thing about broccoli is that there are four interesting things about broccoli. Number One. Nobody knows how to spell it. Number Two. No matter how long you boil it, it's always cold by the time it reaches your plate. Number Three. It's green. #broccoli";
bleep(word, sentence);
for (int i = 0; i < sentence.size(); i++) {
std::cout << sentence[i];
}
std::cout << "\n";
}
functions.h
void bleep(std::string word, std::string &text);
void asterisk(std::string word, std::string &text, int i);
functions.cpp
#include <string>
void asterisk(std::string word, std::string &text, int i) {
for (int k = 0; k < word.size(); ++k) {
text[i+k] = '*';
}
}
void bleep(std::string word, std::string &text) {
for (int i = 0; i < text.size(); ++i) {
int match = 0;
for (int j = 0; j < word.size(); ++j) {
if (text[i+j] == word[j]) {
++match;
}
}
if (match == word.size()) {
asterisk(word, text, i);
}
}
}
On this line:
if (text[i+j] == word[j])
you are indexing too far into text. If you index out of bounds, that invokes undefined behavior. Anything can happen, including working on one platform, but not on another.
Since you only want to find complete words, you can make the index i stop earlier:
for (int i = 0; i < text.size() - word.size(); ++i)

Strange output from running program

I've wrote some code about arrays and strings, which I'm not comfortable working with(I'm a newbie). This bug is a runtime issue, since the compiler didn't yell at me when this program compiled. I'm totally stuck about this, and don't know why this happened.
# include<iostream>
# include<cstdio>
# include<cstring>
# include<string>
using namespace std;
int main() {
char in[100];
gets(in);
int len = strlen(in);
std::string s(in);
int count = 0;
for (int i = 0; i < len; i++) {
if (s.at(i) == ' ') {
count += 1;
}
}
int i = 0;
char rec[100];
for (int j = 0; j < len; j++) {
if (s.at(j + 1) != ' ') {
i += 1;
rec[i] = s.at(j);
} else {
i += 1;
rec[i] = s.at(j);
}
}
for (int m = 0; m < i; m++) {
cout << rec[m];
}
//cout << count;
}
Suppose the user input is "Hello World" (without the quotes). It was supposed to return "Hello", but instead got a error saying the following:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
and what followed was a popup to report to the Microsoft team.
Check "at" and have a close look at some programmers dude comment again:
http://www.cplusplus.com/reference/array/array/at/
It throws out_of_range if n is out of bounds.
Oh and please, especially when asking others:
Dont use 1-letter-variables
Dont use variable names such as "count" or "rec" that are hard to interpret

Working with vectors C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Complicated question, probably simple answer. So the program I need to make cannot include any library other than String, iostream, and vector. I need to create a program that has 3 functions. One that creates an integer vector, one that reverses a vector, and one that prints a vector. In order to take in values I need to use getline to intake a string, if the string states quit, we stop putting new values into it. Other wise we need to test if its an integer(positive or negative) and add it to the vector. My code is starting to get complicated so I really need some help. Below is what i have so far. I'm also using Visual Studio, if that matters. Thanks for any help in advance! The question I have is when I run the program, it will only output the first digit. I don't know why and would like to know what I'm doing wrong.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<int> CreateVector()
{
string tempvariable;
bool quit = false;
vector<int> userinput;
cout << "Please enter in an integer, type 'quit' to exit " << endl;
while (!quit)
{
getline(cin, tempvariable);
if (tempvariable == "quit")
quit = true;
else
{
bool isaninteger = true;
for(int i = 1; i <= tempvariable.size(); i++)
{
if (tempvariable[i] = "-" || isdigit(tempvariable[i]))
continue;
else
{
cout << "You entered in an incorrect option, please enter in a correct option" << endl;
cin.clear();
cin.ignore();
isaninteger = false;
break;
}
}
if (isaninteger)
userinput.push_back(stoi(tempvariable));
cout << "Please enter in an integer, type 'quit' to exit " << endl;
}
}
return userinput;
}
void printVector(vector<int> userinput)
{
int amountofspots = userinput.size();
cout << "Your Vector is ";
for (int i = 0; i < amountofspots; i++)
{
if (i = (amountofspots - 1))
cout << userinput.at(i) << endl;
else
cout << userinput.at(i) << " , ";
}
}
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 0; i < amountofspots; i++)
tempvector.push_back(userinput.at(amountofspots - i));
for (int i = 0; i < amountofspots; i++)
userinput.pop_back();
for (int i = 0; i < amountofspots; i++)
userinput.push_back(tempvector.at(i));
}
int main()
{
vector<int> CreatedVector = CreateVector();
printVector(CreatedVector);
reverseVector(CreatedVector);
printVector(CreatedVector);
system("pause");
return 0;
}
Change if (i = (amountofspots - 1)) to if (i == (amountofspots - 1)) in the loop in printVector().
Change tempvariable[i] = "-" to tempvariable[i] == '-' in CreateVector().
= is the assignment operator, == is the comparison operator. Also, single characters are surrounded by single quotes, not double quotes.
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 0; i < amountofspots; i++)
tempvector.push_back(userinput.at(amountofspots - i));
should probably be
void reverseVector(vector<int>& userinput)
{
int amountofspots = userinput.size();
vector<int> tempvector;
for (int i = 1; i < amountofspots+1; i++) // Index error
tempvector.push_back(userinput.at(amountofspots - i));
The following:
for(int i = 1; i <= tempvariable.size(); i++)
{
if (tempvariable[i] = "-" || isdigit(tempvariable[i]))
Must become:
for(int i = 0; i < tempvariable.size(); i++)
{
if (tempvariable[i] == '-' || isdigit(tempvariable[i]))
Explanation:
String indices start from 0 and end at size() - 1.
[i] returns a single char. "-" is not a single char but an entire string literal. You cannot directly compare a single char with an entire string. -, however, is a single char, so that comparison will work.
= is not comparison but assignment. == is used for comparison. As your compiler should have warned you!
Note that there are further problems with your code:
if (i = (amountofspots - 1))
You are again mixing assignment and comparison. Make that ==. And pay attention to compiler warnings!
And finally, isdigit is not exactly a great function. In order to really use it correctly, you'd first have to cast the operand to int and at the same time make sure it is not an invalid value, as documented here.
Why don't you just catch the exception thrown by stoi if the specified string cannot be parsed?