C++ crashing when reading strings and storing on a vector - c++

#include <iostream>
#include <vector>
using namespace std;
typedef vector<string> VS;
void back(VS &paraules, VS &sol, int n, int i) {
if(i == n) {
cout << "{" << sol[0];
for(int j = 1; j < n; j++) {
cout << "," << sol[i];
}
cout << "}" << endl;
}
else {
for(int j = 0; j < n; j++) {
sol[i] = paraules[j];
back(paraules, sol, n, i+1);
}
}
}
int main() {
int n;
cin >> n;
VS sol(n);
VS paraules(n);
for(int i = 0; i < n; i++) {
cin >> paraules[i];
}
cout << "This won t print";
back(paraules, sol, n, 0);
}
Pasted the whole code now. A backtracking that takes n words, and just prints all the permutations of the words.
I initially thought it was a problem with the reading since the this wont print wasn't printing. After some testing, I've discovered that commenting the function call on the last line makes the error disappear, and the code doesn't crash anymore.
So it's maybe the function? This still doesn't explain why it's not printing, since the call happens after the cout.
As an example input might be:
2 hi bye

It appears that you are going out of bounds in your back function for loop due to the if statement, try using n-1 instead
if(i == n-1)

The problem is that for the case when i == n is true, you've the statement:
cout << "," << sol[i]; //this leads to undefined behavior
In the above shown statement, the size of the vector sol is n. But note since i is equal to n in this case, you are going out of bounds by writing sol[i] and this will result in undefined behavior.
This is because, the indexing starts from 0 and not 1.
For example, say the vector sol size is 4. That is n = 4.
Now what you're essentially doing is :
cout << "," << sol[4];
But you can only safely use elements upto index 3, i.e., using sol[0], sol[1], sol[2], sol[3] is safe. On the other hand, using sol[4] leads to undefined behavior.
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
For example here the program doesn't seem to crash but here it does crashes.
1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

I don't believe there is an issue with the code itself. You are getting segment faults, but it would be from something else.
However, I am assuming your code looks like this:
#include <vector>
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
vector<string> v(n);
for(int i = 0; i < n; i++) {
cin >> v[i];
}
}
Because your code is missing a ending parenthesis, and a #include <iostream>. Would you mind copy and pasting your entire code, or linking a repository?

Related

Exception case: checking to see if the element already exists in an array c++

I'm currently learning c++. I got stuck in this little problem with the exception.
A program asks users to enter 5 integers in an array. I need the program to manage an exception that requests the input of an element again if it already exists.
Here is my code, I figured out the global structure, but the problem is if you enter 0 the program will throw out an exception "already exists", that's not the result I wanted. I know where this comes from, T[j] was not defined in for loop, but I don't know how to deal with it. Could anyone help me to improve it, please? other solutions are also welcomed.
#include<iostream>
#include <vector>
#include<cstdlib>
using namespace std;
int main(){
int i=0,j=0;
int temp;
vector<int>T(5);
do{
try{
cout<<"user input "<<(i+1)<<":";
cin>>temp;
//T[j]= 'a000000000000000000'; //I tried to define T[j], that's maximum I can do
for(j=0;j<=i;j++){
if(T[i]==T[j])
throw(0);
}
T[i]=temp;
i++;
}
catch(const int){
cout<<"Error: value already exists, try again"<<endl;
}
} while(i<sizeof(T)/sizeof(int));
for(i=0;i<sizeof(T)/sizeof(int);i++){
cout<<T[i]<<endl;
}
return 0;
}
This line creates a vector which contains 5 ints. All ints in the vector are zero:
vector<int>T(5);
This line runs a loop. Since i is zero, it runs the loop one time, where j is equal to zero, because j<=i is true, because both of them are zero.
for(j=0;j<=i;j++){
This line checks whether T[i] equals T[j], which it does, because i and j are both zero, and T[0] equals T[0].
if(T[i]==T[j])
This line throws an exception.
throw(0);
Did you spot the bug yet? Maybe you don't want to run the loop where j is equal to i. Maybe you want to loop while j<i instead of j<=i. So if i is 5, j goes from 0 to 4 instead of 0 to 5, and if i is 0, the loop does not run at all.
Also, as Mark Ransom pointed out, this is wrong:
sizeof(T)/sizeof(int)
It should be
T.size()
sizeof(T)/sizeof(int) would work for an array, but not for a vector. You want T.size() instead.
If there isn't a requirement for the numbers to be output in the same order as they were input, a std::set (or std::unordered_set) would work well
#include <iostream>
#include <set>
int main()
{
constexpr int NUMBERS_TO_READ{5};
std::set<int> numbers;
int i = 0;
do
{
int temp;
std::cout << "user input " << (i+1) << std::endl;
std::cin >> temp;
if (numbers.find(temp) != numbers.end())
{
//temp is already in the set
std::cout << "Value " << temp << " already exists, try again!" << std::endl;
}
else
{
//temp isn't in the set. add it.
numbers.insert(temp);
i++;
}
}
while (i < NUMBERS_TO_READ);
for (const auto num : numbers) std::cout << num << std::endl;
}

Trying to create a better loop for naming array elements

I have started studying arrays and have just started making some practice but I am having some problems with using loops to name the elements inside of a specific array.
I was trying to make this piece of code that assigned the numbers from 1 up to 12(to resemble the months of the year) to the ints inside of the array, this is what I came up with:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int array[12];
for (int i = 0; i < 12;) {
cout << "Month number " << i + 1 << endl;
array[i] = (i++);
}
return 0;
}
What I don't like about this is the fact that I had to leave the increment/decrement space inside of the for loop empty. I had initially tried making the code look something like this:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int array[12];
for (int i = 0; i < 12; i++) {
cout << "Month number " << i + 1 << endl;
array[i] = i++;
}
return 0;
}
But this way, even if the first element of the array came out correct, the subsequent ones didn't. I think the reason for this is that the i++ in the last statement of the loop makes the value of i increment but I couldn't find a way around it without having to add another line with i-- or doing as I did in the first code I posted.
Could anyone offer me a hand in understanding how to make it so that i can store the value of i, incremented by one, inside of that specific array element, without incrementing it for the whole loop(if it is possible)?
I know there are ways around it, just like I showed in the first code i posted, but it's something that's bugging me and so I would like to make it more visually pleasing.
Please, keep in mind that I am just a beginner :)
Thanks in advance for the answers, and sorry for the long question.
Edit: Apparently, coding like this:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int array[12];
for (int i = 0; i < 12; i++) {
cout << "Month number " << i + 1 << endl;
array[i] = i + 1;
}
cout << array[4] << endl;
return 0;
}
makes it so that the program works correctly and looks like I wanted, but I can't comprehend why it does :(
Edit 2: Apparently, as UnholySheep pointed out, I missed on the fact that + 1 does not modify the value of the integer, while ++ does.
Thanks to everyone that answered and explained how ++ and +1 work!
Simply do i+1 again.
for (int i = 0; i < 12; i++)
{
cout << "Month number " << i + 1 << endl;
array[i] = i + 1;
}
Now it's obvious you actually want to start at 1 and go to 12, so this seems somewhat better with less repetition:
for (int i = 1; i <= 12; i++)
{
cout << "Month number " << i << endl;
array[i-1] = i;
}
EDIT: As for your edit, the reason why this works is because i++ operator works on the particular i variable. It increments that existing i by one, making it so that the next time you access i, it will be 1 more than it was before.
Writing i+1, on the other hand, creates a completely new, temporary, variable (actually a constant). So when you write
array[i] = i+1;
you're saying that you want i to remain unchanged, but you want to create a new number, one bigger than i, and put that new number into the array.
You can even write it out longer to be completely explicit:
int newNumber = i+1;
array[i] = newNumber;
for (int i = 0; i < 12; i++) {
cout << "Month number " << i + 1 << endl;
array[i] = i+1;
}
No reason to increment i in the loop

adding modulus to rand() in c++ affects execution outside a for loop, why and how to remedy?

I am a c++ beginner and I hope you could help me with some of the fun I am having, you all know what I actually mean.
Here is a snippet of c++ code that I will follow with a brief explanation my problem:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() {
// this first for loop doesn't affect the execution of the first cout statement.
for (int i = 51; i >= 0; i--) {
srand(time(NULL));
int j = rand();
cout << j << endl;
};
cout << "first cout outside the first for loop" << endl; // executes fine
// this second for loop affects the execution of the following cout statement.
for (int i = 51; i >= 0; i--) {
srand(time(NULL));
int j = rand() % i; //by just adding % i, the next cout statement doesn't execute!
cout << j << endl;
};
cout << "second cout outside the second for loop" << endl; // doesn't execute
}
All right, so, I hope the issue is obvious. To put it in words, why adding the modulus i to the rand() in the second for loop prevents the second cout statement from execution? It took me a whole lot of time to pinpoint what seems to be a big problem in my entire class implementation to this single line. Any feedback/advise/explanation is greatly appreciated.
Cheers.
Programs that execute undefined behavior can have any apparent behavior, including code "in the past" not executing.
You do %0 at the end of your loop. This makes earlier print statements not output. That is acceptable behavior as far as C++ is concerned.
Don't do undefined behavior.

Coordinate system with an Ordinate and Abscissa

I'm currently having a problem making a code for a Coordinate system.
In the exercise I'm doing, I want to create a coordinate system with an Ordinate/Abscissa and a defined letter (for example dot A)
I must put information for 25 dots and it must control all dots with the same letter. They should be in a circle with a (0;0) coordinate beginning. If the information given about the 25 dots do not meet the set condition the selected dots must have new reentered information to meet the condition without changing the given values of the previous dots(which meet the expectations). It also should have all the information for dots which have 2 positive coordinates
here's the code I made. I'd be really thankful if someone helped me out.
#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
int main(){
int dotX[23];//tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i<23; i++){// Cikal za vavejdane na masivite
cout << "Abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "Ordinata \t" << i + 1 << endl;
cin >> dotY[i];
cout << "Ime na tochkata" << endl;
cin >> dotName[i];
if (i >= 1){//IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2));//Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi = broi++;
cout << "abscisa \t" << i + 1 << endl;
cin >> dotX[i];
cout << "ordinata \t" << i + 1 << endl;
cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
float i;
for (float i = 0; i > 10, i++;){
float(dotX < 10);
cout << dotName[i] << endl;
}
}
There are a few big problems with your code.
First of all, the syntax for (float i = 0; i > 10, i++;) is completely wrong. It compiles, but that's just a coincidence. The different command in the for loop control structure should be separated by semicolons (;), not commas (,). The correct code would then be for (float i = 0; i > 10; i++). By the way, you made a typo, I think you meant for (float i = 0; i < 10; i++) (otherwise the for loop never runs since i is initialized to 0 and 0 > 10 is false from the beginning).
Second of all, you're initializing the variable i twice: once with float i; and once in the for loop. That shouldn't compile, although with some compilers it does. There are two options on how to do. The first option is to declare the variable outside of the for loop and just assign it without initializing it in the for loop:
float i;
for(i = 0; i < 10; i++){
//some stuff
}
The second option is to simply declare it in the for loop as you did in the first loop:
for(float i = 0; i < 10; i++){
//some stuff
}
Another mistake that you made is to declare i as a float and then try to access dotName[i]. Whatever you put inside the brackets has to be of type int or something similar (unsigned int, long, etc). Putting a float variable inside those brackets won't compile just like that. If you want to index an array with a float, you need to tell the compiler that you want to convert it to an int like this: dotName[(int)i] or dotName[int(i)]. This is called a cast. However, in your case, I would recommend just declaring i as an int.
Also, float(dotX < 10); is completely wrong, I don't really understand what you're trying to do there. I think you meant to do float(dotX[i] < 10);, but that still doesn't make any sense. What you would be doing there would be converting a bool to a float and then doing nothing with the result. That compiles and isn't wrong, but is completely useless. As I said, I don't understand what you want to do there.
Also, broi = broi++; is correct but useless. broi++; is enough. The ++ operator increments broi by one by itself and then returns the result. What the ++ operator does internally is basically this:
int operator++(int &x){
x = x + 1;
return x;
}
So it already increments the variable automatically without you having to do anything. What you did is the same as doing this:
broi = broi + 1;
broi = broi;
Here, the first line represents the ++ operator and the second line represents the = operator. It's clear that the second line is useless, so you can just remove it. In the same way, in your code, you can remove broi =, leaving simply broi++;.
You also did a few things that aren't recommended, but work just fine since the C++ standard supports them.
First of all, using namespace std; is bad practice. It's recommended to omit it and add std:: in front of cin, cout and endl. If you want to know why using namespace std; is bad practice, it's well explained here. However, I must admit that I personally still use using namespace std; since I think it's simpler.
Second of all, the main function is supposed to return 0, so it's recommended to add return 0; at the end of the main function. The return value of the main function tells what made the program close. The value 0 means that the program closed when it was supposed to. Any other values mean that the program crashed. A complete list of what each return value means is available here. Note that C++ supports omitting return 0; and most compilers add it automatically if it is omitted, but it's still recommended to have it. Also, C doesn't support omitting return 0; and in C it will return whatever happens to be in the memory, making it looked like the program crashed when it ended normally.
Also, #include <stdio.h> is C and although it works in C++, it's not recommended. In C++, it's better to use #include <cstdio>. All standard libraries that end with .h in C can be used in C++ by removing .h and adding a c at the beginning. That's also the case with cmath: in C, it would be #include <math.h> and in C++, it's #include <cmath>.
A good version of your code would therefore be:
#include <iostream>
#include <cmath>
#include <cstdio>
int main(){
int dotX[23]; //tri masiva
int dotY[23];
char dotName[23];
for (int i = 0; i < 23; i++){ // Cikal za vavejdane na masivite
std::cout << "Abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "Ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
std::cout << "Ime na tochkata" << std::endl;
std::cin >> dotName[i];
if (i >= 1){ //IF operatora i cikula za obhozhdane na masiva i presmqtane na distanciite
bool flag = true;
while (flag){
double distance = sqrt(pow(dotY[i] - dotY[i - 1], 2) + pow(dotX[i] - dotX[i - 1], 2)); //Formula za presmqtane na razstoqniqta
if (distance <= 6) {
char broi;
broi++;
std::cout << "abscisa \t" << i + 1 << std::endl;
std::cin >> dotX[i];
std::cout << "ordinata \t" << i + 1 << std::endl;
std::cin >> dotY[i];
}
else{
flag = false;
}
}
}
}
for (int i = 0; i < 10; i++){
float(dotX[i] < 10); //Note that I don't understand what you're trying to do here, so I just changed it to something that compiles
std::cout << dotName[i] << std::endl;
}
}

Why simple program for printing out dividers of the input number stopped working?

here is the code I am having an issue with:
int printDividers(int x)
{
for (int j=0; j<x+1; j++)
{
if (x%j==0) cout << j << ", ";
}
}
int main()
{
int z;
cout << "Enter a number and the program will print out it's dividors:" << endl;
cin >> z;
printDividers(z);
return 0;
}
After entering your number it says main.exe stopped working. I haven't figured out why, I can't spot the error in the code.
When i==0, we will run the test if (x%0 == 0) which isn't a valid statement because it attempt to divide by 0. Hence, your program will might crash. Its behavior is undefined
You're out of luck, you are attempting to compute % 0 in your for loop. Along with integral division by zero, the behaviour on doing this is undefined:
The C++03 Standard states in ยง5.6/4,
[...] If the second operand of / or % is zero the behavior is
undefined; [...]
What is x % 0? (Answer: Undefined Behaviour) This is what causes your run-time error.
Change to this:
for (int j=1; j<x+1; j++)
http://ideone.com/K5vSxt