C++ Segmentation Fault with no pointers (HackerRank) - c++

I solved a problem in Hacker Rank.
Input Format. The first line of the input contains an integer N.The next line contains N space separated integers.The third line contains a single integer x,denoting the position of an element that should be removed from the vector.The fourth line contains two integers a and b denoting the range that should be erased from the vector inclusive of a and exclusive of b.
Output Format. Print the size of the vector in the first line and the elements of the vector after the two erase operations in the second line separated by space.
CODE:
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
int n = 0, x = 0, value = 0;
vector<int> vk, vm;
vk.reserve(100000);
string k, m;
cin >> n;
cin.ignore();
getline(cin, k);
cin >> x;
cin.ignore();
getline(cin, m);
stringstream sk(k);
while (sk >> value)
vk.push_back(value);
stringstream sm(m);
while (sm >> value)
vm.push_back(value);
vk.erase(vk.begin() + x-1);
vk.erase(vk.begin() + vm[0]-1, vk.begin() + vm[1]-1);
cout << vk.size() << endl;
for (int i = 0; i < vk.size(); i++)
cout << vk[i] << " ";
cout << endl;
return 0;
}
But with this test case produce a "Segmentation Fault":
6
1 4 6 2 8 9
2
2 4
Can you help me to review my code and provide some feedback on what is the problem?
EDIT
Thanks to #john for the answer. Here is how it looks without the seg fault:
#include <vector>
#include <iostream>
#include <string>
using namespace std;
int main() {
int n = 0, x = 0, y = 0, z = 0, value = 0;
vector<int> vk;
vk.reserve(100000);
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> value;
vk.push_back(value);
}
cin >> x >> y >> z;
vk.erase(vk.begin() + x-1);
vk.erase(vk.begin() + y-1, vk.begin() + z-1);
cout << vk.size() << endl;
for (int i = 0; i < vk.size(); i++)
cout << vk[i] << " ";
cout << endl;
return 0;
}

You're trying too hard with the your input code. It isn't correct because you seem to be assuming that cin.ignore() will skip the rest of the line, when it only skips the next character (which could be a space). I would guess this is the reason for the seg fault. You can tell how many numbers you have to read after you've read the first one. There is no need to use getline or stringsteam at all.
You don't need the vm vector. It will always contain two values, so just declare two variables. You could also pick much better names for all your variables.
cin >> n;
for (int i = 0; i < n; ++i)
{
cin >> value;
vk.push_back(value);
}
cin >> x >> vm0 >> vm1;

Related

Is integer overflow that evil?

Consider the following code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, k;
cin >> n >> k;
vector<int> a(n);
int sum = 0;
for (auto &it : a) {
cin >> it;
sum += it;
}
cout << sum << "\n";
for (int i = 0; i < n; i++) {
cout << a[i] << " ";
}
cout << endl;
}
Input like (or anything greater than INT_MAX into k)
5 1234567891564
1 2 3 4 5
makes the program print
0
0 0 0 0 0
What actually happens? We don't use the value of k at all.
There is actually no integer overflow in your code. Well in a wider sense it there is, but in a more narrow sense integer overflow would happen for example with:
int k = 1234567891564;
What actually happens is that in this line
cin >> n >> k;
operator>> tries to read a int but fails. 1234567891564 is never actually assigned to k. When reading the input fails 0 will be assigned. Hence k comes out as 0.
Once the stream is in an error state, all subsequent calls to operator>> will silently fail as well. You should always check the state of the stream after taking input. For example:
if (std::cin >> n) {
// input succeeded use the value
} else {
// input did not succeed.
std::cin.clear(); // reset all error flags
}

Subtract each elements of an array consecutively

I have an array and I want to subtract each of the elements consecutively, ex: {1,2,3,4,5}, and it will result to -13 which is by 1-2-3-4-5.
But I don't declare or make those numbers fixed as they're taken from the input (user). I only make it like, int array[100] to declare the size.
Then, to get the inputs, I use the for loop and insert them to the array. Let's say first input is 10, then array[0] must be 10 and so on.
The problem is, how do I subtract them? I have two options:
The first element of the array (array[0]) will subtract the next element (array[1]) right after the user input the second element, and the result (let's say it's int x) will subtract the next element (array[2]) after the user input it and so on.
I'll have the user input all the numbers first, then subtract them one by one automatically using a loop (or any idea?) *These elements thing refer to the numbers the user input.
Question: How do you solve this problem?
(This program will let the user input for as much as they want until they type count. Frankly speaking, yeah I know it's quite absurd to see one typing words in the middle of inputting numbers, but in this case, just how can you do it?)
Thanks.
Let's see my code below of how I insert the user input into the array.
string input[100];
int arrayInput[100];
int x = 0;
for (int i = 0; i >= 0; i++) //which this will run until the user input 'count'
{
cout << "Number " << i+1 << ": ";
cin >> input[i];
arrayInput[i] = atoi(input[i].c_str());
...
//code to subtract them, and final answer will be in int x
...
if (input[i] == "count")
{
cout << "Result: " << x << endl;
}
}
You can/should use a dynamic sized container like std::vector as shown below:
#include <iostream>
#include <vector>
int main()
{
int n = 0;
//ask user how many input he/she wants to give
std::cout << "How many elements do you want to enter: ";
std::cin >> n;
std::vector<int> vec(n); //create a vector of size n
int resultOfSubtraction = 0;
//take input from user
for(int i = 0 ; i < n ; ++i)
{
std::cin >> vec.at(i);
if(i != 0)
{
resultOfSubtraction-= vec.at(i);
}
else
{
resultOfSubtraction = vec.at(i);
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}
Execute the program here.
If you want a string to end the loop then you can use:
#include <iostream>
#include <vector>
#include <sstream>
int main()
{
std::vector<int> vec;
int resultOfSubtraction = 0, i = 0;
std::string endLoopString = "count";
std::string inputString;
int number = 0;
//take input from user
while((std::getline(std::cin, inputString)) && (inputString!=endLoopString))
{
std::istringstream ss(inputString);
if(ss >> number)
{
vec.push_back(number);
if(i == 0)
{
resultOfSubtraction = number;
}
else
{
resultOfSubtraction-= number;
}
++i;
}
}
std::cout<<"result is: "<<resultOfSubtraction<<std::endl;
return 0;
}

write a complete program that will read 3 NUMBers from user and calculates and displays the product only of the positive integers

This is what I've tried so far
// Calculate the product of three integers
#include <iostream> // allows program to perform input and output
using namespace std;
// function main begins program execution
int main()
{
int x; // first integer to multiply
int y; // second integer to multiply
int z; // third integer to multiply
int result; // the product of the three integers
cout << "Enter three integers: "; // prompt user for data
cin >> x >> y >> z;
result = x * y * z;
}
what can i do to solve this question?
EDIT:
If you do not need it to loop use a if instead of a while.
Looks like you need to study some conditional statements try:
result = x*y*z;
while(result < 0){
cout << "Enter three integers: "; // prompt user for data
cin >> x >> y >> z;
}
cout << result << endl;
Should work fine...
I would suggest using a condition to check the number at the input itself:
#include <iostream>
int main() {
int inum1 = 0;
std::cin >> inum1;
if (inum1 < 0) { inum1 = 1; }
int inum2 = 0;
std::cin >> inum2;
if (inum2 < 0) { inum2 = 1; }
int inum3 = 0;
std::cin >> inum3;
if (inum3 < 0) { inum3 = 1; }
std::cout << inum1*inum2*inum3 << "\n";
return 0;
}
Notice that in my example I have used std::cout and std::cin instead of using namespace std
use of using namespace std is fine if you're a beginner or the program is small, but is discouraged for large programs :)
If you find typing std:: tedious, you can instead include the following statements:
using std::cin;
using std::cout;
Also, printf and scanf is usually preferred over cin and cout for fast I/O.

Getting user input upon pressing a space

I am trying to tackle this condition where the user has to input a number n. and then entering n numbers after it on the same line. Therefore my program needs to know this number n before the user continues to input so that the programs knows how large of a dynamic array it needs to save these numbers inputted after n. (It is crucial that all of this happens on one line).
I tried the following but it doesn't seem to work.
int r;
cin >> r;
//CL is a member function of a certain class
CL.R = r;
CL.create(r); //this is a member function creates the needed dynamic arrays E and F used bellow
int u, v;
for (int j = 0; j < r; j++)
{
cin >> u >> v;
CL.E[j] = u;
CL.F[j] = v;
}
You can do that as usual on a single line:
#include <string>
#include <sstream>
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int *array;
string line;
getline(cin,line); //read the entire line
int size;
istringstream iss(line);
if (!(iss >> size))
{
//error, user did not input a proper size
}
else
{
//be sure to check that size > 0
array = new int[size];
for (int count = 0 ; count < size ; count++)
{
//we put each input in the array
if (!(iss >> array[count]))
{
//this input was not an integer, we reset the stream to a good state and ignore the input
iss.clear();
iss.ignore(numeric_limits<streamsize>::max(),' ');
}
}
cout << "Array contains:" << endl;
for (int i = 0 ; i < size ; i++)
{
cout << array[i] << ' ' << flush;
}
delete[] (array);
}
}
And here is the demonstration, you can see that the input is one line 6 1 2 3 4 5 6.
Once again, I did not check everything, so take care of that the way you need.
Edit: added reset of the stream after a bad read.

String arrays output

How can I get the output of this program to work correctly? I'm not sure why the string array won't store my values and then output them at the end of my program. Thanks.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int score[100], score1 = -1;
string word[100];
do
{
score1 = score1 + 1;
cout << "Please enter a score (-1 to stop): ";
cin >> score[score1];
}
while (score[score1] != -1);
{
for (int x = 0; x < score1; x++)
{
cout << "Enter a string: ";
getline(cin,word[x]);
cin.ignore();
}
for (int x = 0; x < score1; x++)
{
cout << score[x] << "::" << word[x] << endl; // need output to be 88:: hello there.
}
}
}
I've corrected your code. Try something like this
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int score[100], score1 = -1;
char word[100][100];
do
{
score1++;
cout << "Please enter a score (-1 to stop): ";
cin >> score[score1];
}
while (score[score1] != -1);
cin.ignore();
for (int x = 0; x < score1; x++)
{
cout << "Enter a string: ";
cin.getline(word[x], 100);
}
for (int x = 0; x < score1; x++)
{
cout << score[x] << "::" << word[x] << endl; // need output to be 88:: hello there.
}
}
OK what have I done? First of all I delete extra {. When I've seen your code for the first time I have no idea if there is do..while loop or while loop in do.while. Next I change string array to char array, just because I know how to read line to char array. When I need to read line to string I always use my own function, but if you really want to use string here is great example. Rest is quite obvious. cin.ignore() is required because new line character stays in buffer so we need to omit it.
EDIT:
I've just found better way to fix your code. Everything is OK but you need to move cin.ignore() and place it just after while (score[score1] != -1);. Because wright now you are ignoring first char of every line and you need only ignore new line after user type -1. Fixed code.
In the first loop, you increment "score1" before the first value is assigned. That places your values in the score[] array starting at index 1. However, in the "for" loop below, you start your indexing at 0, meaning that your score/string associations will be off by one.
Replace
getline(cin,word[x]);
cin.ignore();
with
cin >> word[x];
and then try figuring out where you went wrong.