C++ program has stopped working - c++

I am making a quite simple program, just a little chat bot AI kind of thing, and I have some code, c++ of course, for the program. I don't get any errors but when I run it a window comes up saying program.exe has stopped working, like it stopped responding. My code is:
#include<iostream>
#include<string.h>
#include<cmath>
#include<vector>
#include<ctime>
#include<conio.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
struct strarray{
char* array[];
};
struct keyword{
string keywords;
string responses[];
};
keyword * dictionary = new keyword[2];
keyword defaultr;
keyword getMatch(string key);
string sconvert(string con);
void init();
string getResp(keyword key);
bool cont=true;
int main(int argc, char* argv[]){
string input;
while(cont){
getline(cin,input);
cout << getResp(getMatch(input));
getch();
getch();
}
}
string sconvert(string con){
con.erase(remove_if(con.begin(), con.end(), ::isspace), con.end());
con.erase(remove_if(con.begin(), con.end(), ::ispunct), con.end());
return con;
}
void init(){
srand(time(NULL));
dictionary[0].keywords="hello";
dictionary[0].responses[0]="Hello, how have you been?";
dictionary[0].responses[1]="Hello, have you missed me?";
dictionary[0].responses[2]="Hey, how's it going?";
defaultr.responses[0]="That's interesting, tell me more.";
defaultr.responses[1]="Please, tell me more.";
}
keyword getMatch(string key){
for(int i=0; i<sizeof(dictionary); i++){
if(key==dictionary[i].keywords){return dictionary[i];}
}
return defaultr;
}
string getResp(keyword key){
return key.responses[rand() % sizeof(key)];
}
When I run it, it opens up normally, but after I input something when it comes up it "stops working". Could somebody please tell me what I need to change, and why would be appreciated.
Is there some pointer problem? Or something with the rand? I'm really confused and would appreciate some advice on how to better this program so it actually works.

sizeof(dictionary) will give sizeof(keyword*), probably 4 or 8, so you will iterate over the end of the dictionary array and terminate.
Easiest fix: Define a constant to store the array length.
const dictionarySize = 2;
and use that throughout.
You also need to change struct keyword to:
struct keyword{
string keywords;
string responses[3];
};

first of all u have an infinite loop so the program should work for ever .. I took a glance at the code and using rand() % sizeof(key) is wrong, the responses is not predetermined so either you set it to a specific value for example
struct keyword {
string keywords;
string responses[2];
};
rand() % sizeof(key.responses)
or you make your structure like this
struct keyword {
string keywords;
vector<string> responses;
};
rand() % key.responses.size()
//After setting the responses by push_back for example
there are other ways but this is safer and no memory management needed ...

Related

c++ save and load structures to file

I am currently working on a game project and i am saving a struct with all needed values of a game-object into a file. Saving is completely fine but if i start loading them in it will only load the first 25 of them.
After that i tried with using a while (true) that loads in objects until the last object doesn't get the right type and break out of the loop. This works perfectly fine but is maybe not the most elegant solution to take.
using namespace std;
struct{
const char* type;
int sizeW;
int sizeH;
int collisionLayer;
int textureID;
int positionX;
int positionY;
} loadStruct;
ifstream fileObj;
fileObj.open("level.txt");
if (fileObj.is_open()){
while (!fileObj.eof()){
fileObj.read((char*)&loadStruct, sizeof(loadStruct));
// creating my object out of loadStruct -> working fine
}
fileObj.close();
}
I've tried to remove the check for eof() and simply put a try/catch in the while loop breaking out if error is catched but this idea was not the most elegant and didn't work 100% of the time.
Thanks for "pointing" me to the char* type ... that was seriously the problem causing it to fail. Now i reworked it and also got rid of .eof() and simply check if my type was written or not.
using namespace std;
struct {
char type[20];
int sizeW;
int sizeH;
int collisionLayer;
int textureID;
int positionX;
int positionY;
} loadStruct;
bool reading = true;
ifstream fileObj;
fileObj.open(filename);
if (fileObj.is_open()){
while (reading){
string str = "empty";
strcpy(loadStruct.type, "empty");
fileObj.read((char*)&loadStruct, sizeof(loadStruct));
if (loadStruct.type == str){
reading = false;
break;
}
}
}
fileObj.close();

What is the problem with the following code using constructors for sorting strings?

#include <iostream>
#include <string.h>
using namespace std;
class sorting
{
private:
char str[10];
public:
sorting() {
int i;
for(i=0;i<10;i++) {
cin>>str[i];
}
}
void sort() {
int i,j;
char temp;
for(i=0;i<10;i++) {
for(j=i+1;j<10;j++) {
if(strcmp(str[j],str[j+1])>0) {
strcpy(temp,str[j]);
strcpy(str[j],str[j+1]);
strcpy(str[j+1],temp);
}
}
}
for(i=0;i<10;i++) {
cout<<str[i];
cout<<"\n";
}
}
};
int main() {
sorting s1;
cout<<s1.sort();
return 0;
}
This is a code I have written to sort strings using constructors. It gives me error in the if condition of the code where I have used strcmp. Please review this for I could not get the desired output and it gives me errors.
Problem 1
Like someone already pointed out, you cant use strcopy on chars. If you want to create a string array i would suggest using either char** or std::string*.
Problem 2
In your nested loop you will get an index out of bounds error, due to the fact that once i reaches a value of 8, j will be 9, which means that when you try to access str[j+1] which evaluates to str[10], you will get said error.

function returns an empty vector

I am trying to return a vector of strings from a function, but every time I do so I get an empty vector.However when I try to print the vector in the function itself it's not empty but when I try to print the returned vector I am getting nothing printed.
#include <iostream>
#include <vector>
using namespace std;
vector<string> permute(string S, string chosen){
vector<string> permutated_strings;
if(S.empty())
permutated_strings.push_back(chosen);
else{
for(int i=0;i<S.length();i++){
char c = S[i];
chosen += c;
S.erase(i,1);
permute(S,chosen);
//backtrack
chosen.erase(chosen.length()-1,1);
S.insert(i,1,c);
}
}
return permutated_strings;
}
int main() {
//code
int test;
cin >> test;
while(test)
{
string S;
cin >> S;
vector<string> vec;
vector<string> ::iterator i;
vec = permute(S,"");
for(i=vec.begin();i!=vec.end();i++)
cout<<*i<<" ";
cout << "\n";
test--;
}
return 0;
}
When I am printing the vector in the permute function I am getting the right result but when I am printing the vector in main function it is empty. Can somebody please point me out the mistake I am doing.
You need to save result of recursive call of permute method.
auto result = permute(S,chosen);
permutated_strings.insert(permutated_strings.end(), result.begin(), result.end());
I got the mistake that I was doing. I really hate answering my own questions but it may help someone like me in the future.
I have changed -
vector<string> permutated_strings;
to
static vector<string> permutated_strings;
in the permute function so that previous returns from the recursive calls are not lost. By doing so I am getting the desired result.
Thanks everyone for pointing me to the mistake that I was doing.
EDIT
As suggested by #M.M that this solution may cause problem in future. And I have realized that if I give "test" value as 2 the final value in the permutated_strings will be from test=1 + test =2 which is not which I wanted. So this solution is not the perfect one. Instead I am accepting solution from #BartekPL.

How to initialize this array in a clean way?

I am trying to initialize this array in C++ :
C++
#include<iostream>
using namespace std;
int main(){
int arr[100];
int i = 10;
while(i){
cin >> arr[--i];
}
return 0;
}
This initializes the array perfectly, but it returns a negative status. How can I solve it?
The status code means the program didn't get to the last line of your main() function (where it should be return 0), but got killed instead. I guess you just stopped it with CTRL+C.

C++ Int getting random value after function that isn't supposed to change it

Okay - yes, this is homework, but it isn't mine. I have a friend taking an introductory C++ course who asked me for help, and I helped them write this program, but there is one weird bug that I can't figure out. Any helpful suggestions would be greatly appreciated. Thanks!!
The following is the code. The problem is that after the add_loop function, the int loop_size gets a random value. Within the function, it has the value it is supposed to have, but afterwards, it changes.
#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define STRING_SIZE 50
void get_template (char StemLoop [])
{
char Template [STRING_SIZE];
cout<<"Please enter a template for the stem:";
cin>> Template;
strcpy (StemLoop, Template);
}
void add_loop (char StemLoop[], int loop_size)
{
char random_loop [STRING_SIZE];
int random_array[STRING_SIZE];
for (int i=0; i<loop_size; i++)
{
random_array[i] = rand() % 4;
if (random_array[i]==0)
random_loop[i]='A';
else if (random_array[i]==1)
random_loop [i]='U';
else if (random_array[i]==2)
random_loop [i]='G';
else if (random_array[i]==3)
random_loop [i]='C';
}
strcat (StemLoop, random_loop);
}
void add_complement(char StemLoop[], int loop_size)
{
int x =strlen(StemLoop);
int j=0;
char complement [STRING_SIZE]="";
for (int i=0; i<(x-loop_size); i++)
{
if (StemLoop[i]=='A')
complement[j]='U';
else if (StemLoop[i]=='U')
complement[j]='A';
else if (StemLoop[i]=='G')
complement[j]='C';
else if (StemLoop[i]=='C')
complement[j]='G';
j++;
}
strcat(StemLoop,complement);
}
void main()
{
int loop_size=0;
cout<<"Please enter the size of the loop: ";
cin>>loop_size;
char StemLoop [STRING_SIZE];
//Part1: the template
get_template (StemLoop);
//This is supposed to be the function that adds the loop of random "genes".
//It works, and within it the int loop_size is the correct value...
add_loop (StemLoop, loop_size);
/*...but here it is a random number. It's as if the random value generated
within the function is getting assigned to it. And of course, it's throwing off the
entire program.
*/
//Part#3: the complement
add_complement (StemLoop, loop_size);
cout<<"The complete stem-loop strand is:"<<StemLoop<<endl;
}
You're not 0-terminating random_loop before you use it in strcat, so strcat can write all over your stack. Try this:
random_loop[i] = 0;
strcat (StemLoop, random_loop);
A more serious problem could be that you're not checking you have enough room to strcat.