Why is this program(rather the segment) crashing the whole program - c++

I have been scratching my head to figure out why is my program is crashing. My aim was to scan a string and get frequency of each sub string !
The Real part where the program is crashing (M is a map of string,int type)
My Input: the string is "abab" and the program crashes when i=0 and j is equal to 3 just at the M[e]++ statement!
for(i=0;str[i];i++)
{
char temp[5001];
k=0;
cout<<str[i]<<endl;
for(j=i;str[j];j++)
{
temp[k]=(char)str[j];
k++;
temp[k]='\0';
string e(temp);
M[e]++;
cout<<j<<endl;
}
}
MAIN Method
int main()
{
ini();
int t,N,i,j,Q,buff,k=0;
char str[5001];
scanf("%d",&t);
map <string ,int > M;
map <string , int >::iterator ii;
for(;t--;)
{
scanf("%d%d",&N,&Q);
scanf(" %s",str);
for(i=0;str[i];i++)
{
char temp[5001];
k=0;
cout<<str[i]<<endl;
for(j=i;str[j];j++)
{
temp[k]=(char)str[j];
k++;
temp[k]='\0';
string e(temp);
M[e]++;
cout<<j<<endl;
}
}
for(ii=M.begin();ii!=M.end();++ii)
F[ii->second]++;
F2[N]=F[N]%MOD;
for(i=N;i>=1;i--)
if(F[i])
for(j=i-1;j>=1;j--)
F2[j]=(F[j]+((long long)F[i]%MOD*C(F[i],j)%MOD)%MOD)%MOD;
for(i=0;i<Q;i++)
{
scanf("%d",&buff);
printf("%d\n",F2[buff]);
}
}
return 0;
}
Note
int F[5001],F2[5001];
are declared globally too.

As requested:
#include <iostream>
#include <string>
#include <map>
#define MOD 10
using namespace std;
int C( int a, int b ){
return 5;
}
int F[5001],F2[5001];
int main()
{
int t,N,i,j,Q,buff,k=0;
string str(5001, ' ');
cin >> t;//scanf("%d",&t);
cin.ignore( 256, '\n' );
map <string ,int > M;
map <string , int >::iterator ii;
for(;t--;)
{
cin >> N;
cin.ignore( 256, '\n' );
cin >> Q;
cin.ignore( 256, '\n' );
//scanf(" %s",str);
getline(cin,str);
for(i=0;str[i];i++)
{
char temp[5001];
k=0;
cout<<str[i]<<endl;
for(j=i;str[j];j++)
{
temp[k]=(char)str[j];
k++;
temp[k]='\0';
string e(temp);
M[e]++;
cout<<j<<endl;
}
}
for(ii=M.begin();ii!=M.end();++ii)
F[ii->second]++;
F2[N]=F[N]%MOD;
for(i=N;i>=1;i--)
if(F[i])
for(j=i-1;j>=1;j--)
cout << "hello";F2[j]=(F[j]+((long long)F[i]%MOD*C(F[i],j)%MOD)%MOD)%MOD;
for(i=0;i<Q;i++)
{
scanf("%d",&buff);
printf("%d\n",F2[buff]);
}
}
return 0;
}
For testing purposes, because there was no MOD and C definitions given, for MOD I used a constant int and C an empty function that received those parameters and simply returned a value.
Instead of scanf, I used cin for the inputs and later cin.ignore() to clear the input buffer so that it won't skip the next cin. Changed str to type string. Used getline to get input for string, as this reads the enitre line from the input cin. And that is it for modifications.

for(i=0;str[i];i++)
{
for(j=0;str[j+i];j++)
{
M[str.substr(j,i+1)]++;
}
}
Replace internal two for loops with this and check whether it's crashing or not . If still that means you may be running this program on windows.In that case use this.
for(i=0;str[i];i++)
{
for(j=0;str[j+i];j++)
{
std::string sstr = str.substr(j,i+1);
if ( M.find ( sstr ) == M.end() ){
M.insert( std::make_pair ( sstr , 0 ) ) ;
}
else
M[str.substr(j,i+1)]++;
}
}

Related

C++ - Storing user input string separated by commas into vector

I have a code written that performs this task to a certain extent. But, I would like to how to alter my code so that I can store as many string inputs the user wants to enters into the vector.
Here is my code:
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
int main ()
{
string input = "";
cout << "Input: ";
cin >> input;
string a,b;
for(int i = 0; i<input.size(); i++)
{
if(input.at(i)==','){
a=input.substr(0,i);
b=input.substr(i+1);
}
}
vector<string> objects;
objects.push_back(a);
objects.push_back(b);
for (int k = 0; k < 2; k++) {
cout << objects[k] << endl;
}
return 0;
}
So far, it can only recognize and store two inputs separated by commas. I am very new to coding so could someone show me a way to make this into a loop and take in as many inputs as the user enters?
Thank you.
There are much simpler approaches to parse an input string using stringstreams:
string a;
vector<string> objects;
for(stringstream sst(input); getline(sst, a, ','); ) // that's all !
objects.push_back(a);
copy (objects.begin(), objects.end(), ostream_iterator<string>(cout," ; ")); // display all
Online demo
You need to change your code in order to work for any number of user input.
The logic is to push every sub string between the commas into vector.
vector<string> objects;
for(int i = 0,j=0; i<input.size(); i++)
{
if(input.at(i)==',' || input.at(i)=='\0'){
objects.push_back(input.substr(j,i-j)); //pushing the sub string
j=i+1;
}
}
In order to print the vector first you have to find the size of the vector,then simply iterate over to print it.
//display
int l=objects.size();
for (int k = 0; k < l; k++) {
cout << objects[k] << endl;
}
Note: If you want your code to work for strings with spaces in between , for example: a ,b ,c ,d then use getline(cin,input); to take input from user.
You can see running code here or as a github gist.
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <string>
void ParseCSV(
std::vector< std::string >& output,
const std::string& csv )
{
int q = 0;
int p = csv.find(",");
while( p != -1 )
{
output.push_back( csv.substr(q,p-q) );
q = p+2;
p = csv.find(",",q);
}
// The terminating comma of the CSV is missing
// so we need to check if there is
// one more value to be appended
p = csv.find_last_of(",");
if( p != -1 )
{
output.push_back( csv.substr( p+2 ) );
}
else
{
// there was no comma
// this could be because the list is empty
// it could also be because there is just one element in the list
if( csv.length() > 1 )
output.push_back( csv );
}
}
int main()
{
std::string test("this is my list, a, b, c, d, end of line");
std::vector< std::string > split;
ParseCSV( split, test );
for( auto& s : split )
std::cout << s << std::endl;
}
As suggested by Christophe, using stringstream is much better. No special case handling needed! I use a while loop - it seems clearer what is happening.
void ParseCSV2(
std::vector< std::string >& output,
const std::string& csv )
{
std::stringstream sst(csv);
std::string a;
while( getline( sst, a, ',' ) )
output.push_back(a);
}

Using next_permutation to get palindrome string

I'm trying to make a program that tries every permutation in the string to check if it can create palindrome string or not. If not it deletes one char and tries again and so on till you find a solution. I can't figure why it gives me a segmentation fault. Here is my code:
bool IsPalindrome(string s){
string t;
int x=s.size()-1;
for(int i=x;i>=0;i--)
t+=s[i];
if(s==t)
return true;
else
return false;
}
void generate_permutation(string s,int i){
sort(s.begin(),s.end());
do{
if(IsPalindrome(s)){
if(i%2==0){
cout<<"First"<<endl;
exit(0);
}
else{
cout<<"Second"<<endl;
exit(0);
}
}
}while(next_permutation(s.begin(),s.end())) ;
}
int main(){
string s;
cin>>s;
int i=0;
while(s.size()>=1){
generate_permutation(s,i);
s.erase(s.begin()+i);
i++;
}
}
int i=0;
while(s.size()>=1){ // size() goes down to 1
generate_permutation(s,i);
s.erase(s.begin()+i); // the i'th element is always the one erased
i++; // i goes up and up
Perhaps you intend to remove the first or last character, instead of the first, then the second, then the third…
Probably this is what you want
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
for (cin >> s; s.size(); ) {
sort(s.begin(), s.end());
do {
if (equal(s.begin(), s.end(), s.rbegin())) { // Palindrome check
cout << s << endl;
return 0;
}
} while (next_permutation(s.begin(), s.end())); // all permutations
string::iterator it = unique(s.begin(), s.end(), [](char a, char b) {
return a != b;
}); // first non repeating char
s.erase(it != s.end() ? it : s.begin()); // erase a char
}
return 0;
}
Sample Input
abaca
Sample Output
aaa
See demo http://ideone.com/VgTEgS.

to check type of input in c++

## To check type of data entered in cpp ##
int main()
{
int num;
stack<int> numberStack;
while(1)
{
cin>>num;
if(isdigit(num))
numberStack.push(num);
else
break;
}
return(0);
}
If I declare a variable as interger, and I input an alphabet, say 'B', instead of the number, can I check this behavior of user? My code above exits when first number is entered and does not wait for more inputs.
First of all, the std::isdigit function checks if a character is a digit.
Secondly, by using the input operator >> you will make sure that the input is a number, or a state flag will be set in the std::cin object. Therefore do e.g.
while (std::cin >> num)
numberStack.push(num);
The loop will then end if there's an error, end of file, or you input something that is not a valid int.
First take your input as string
Using builtin libraries like isdigit() classify it as an integer
else if it contains '.'then its a float
else if it a alphanumerical the it is a string thats it
Code for this is below,
#include<iostream>
#include<string.h>
using namespace std;
int isint(char a[])
{
int len=strlen(a);
int minus=0;
int dsum=0;
for(int i=0;i<len;i++)
{
if(isdigit(a[i])!=0)
dsum++;
else if(a[i]=='-')
minus++;
}
if(dsum+minus==len)
return 1;
else
return 0;
}
int isfloat(char a[])
{
int len=strlen(a);
int dsum=0;
int dot=0;
int minus=0;
for(int i=0;i<len;i++)
{
if(isdigit(a[i])!=0)
{
dsum++;
}
else if(a[i]=='.')
{
dot++;
}
else if(a[i]=='-')
{
minus++;
}
}
if(dsum+dot+minus==len)
return 1;
else
return 0;
}
int main()
{
char a[100];
cin>>a;
if(isint(a)==1)
{
cout<<"This input is of type Integer";
}
else if(isfloat(a)==1)
{
cout<<"This input is of type Float";
}
else
{
cout<<"This input is of type String";
}
}
use cin.fail() to check error and clean the input buffer.
int num;
while (1) {
cin >> num;
if (cin.fail()) {
cin.clear();
cin.sync();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
if (num == -1) {
break;
}
numberStack.push(num);
}

Why the code is printing 0 at first

#include <cstdio>
#include <string>
#include <set>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
int t, z;
scanf("%d", &t);
while (t--) {
string buf, str;
getline(cin, str);
stringstream ss(str);
int cnt = 0;
set<string> tokens;
while (ss >> buf) {
tokens.insert(buf);
}
for (set<string>::iterator it = tokens.begin(); it != tokens.end(); ++it) {
cnt++;
}
printf("%d\n", cnt);
}
return 0;
}
This code is just used for counting the number of different words present in a string. e.g for input
i am i
wil give output
2
But when i enter the test cases it first gives 0 as output neglecting the last test case..what is the reason for it?? and how can it be corrected??
Here is the link
Your scanf is only reading the integer - it doesn't read the end of line. So your first "line" is the rest of the line with "4" on it. Either read to the end of the line or use the solution from user3477950.
Sameer,
modify your code thus:
int main()
{
char eatNewline = '\0';
int t, z;
scanf("%d", &t);
eatNewline=getchar(); //Eat the enter key press.
while (t--)
{
string buf, str;
getline(cin, str);
stringstream ss(str);
int cnt = 0;
set<string> tokens;
while (ss >> buf)
{
tokens.insert(buf);
}
for (set<string>::iterator it = tokens.begin(); it != tokens.end(); ++it)
{
cnt++;
}
printf("%d\n", cnt);
}
return 0;
}
[root#saas ~]# ./tst
4
now do it now
3
now do it now
3
I am good boy
4
am am
1
Please let me know if that helps you! :)
because after you scanf("%d", &t), the tailing \n is still in the input string buffer.
To fix this problem, you can change it to:
scanf("%d ", &t); // add a space after %d to catch the '\n' character
or add
cin >> ws;
or use gets(...) etc.

how to decleare a 1D double array

Data input from the keyboard.The length of array maybe very long.
I want to finish inputing when press ENTER twice.
the numbers separated by space, tab or ",". how to detect the length n?
I have tried like this:
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
void main()
{
bool flag=true;
unsigned n=0,i;
double x;
string line,str;
istringstream iss;
cout<<"input your numbers."<<endl;
count<<"Press the Enter key twice finish data inputting."<<endl;
while(flag)
{
getline(cin,line);
str+=line+' ';
if(line.empty())
flag=false;
}
// get the length n
iss.str(str);
while(iss>>x)
{
n++;
}
double *v=new double[n];
iss.seekg(0);
for(i=0;i<n;i++)
iss>>v[i];
for(i=0;i<n;i++)
{
cout<<v[i];
if(i<n-1)
cout<<' ';
}
cout<<endl;
delete []v;
}
I am a novice. Help me, Please!
Try this After taking the input in variable line do this:
#include<iostream>
#include<string>
#include<sstring>
using namespace std;
void main()
{
bool flag=true;
unsigned n,i=0;
double x;
string line,str;
istringstream iss;
cout<<"input your "
getline(cin,line);
int c=0;
char * pch;
pch = strtok (line," ,");// this will work for space and comma but you can add your own specifiers
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,");
c++;
}
return(c);// will give the length of arry.
}
Man to declare 1D array
the syntax is
void main()
{
int array[5];
//to initalize;
for(int i=0;i<5;i++)
{
array[i]=i;
}
for(int i=0;i<5;i++)
{
cout<<array[i]<<" ";
}
// and to declare dynamically
int * array=new int[5];
}
I have solved this problem.
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
void main()
{
bool flag=true;
unsigned n=0,i;
double x;
string line,str;
istringstream iss;
cout<<"input your numbers."<<endl;
cout<<"Press the Enter key twice finish data inputting."<<endl;
//Brecause data may come from clipboard and have multi line.
while(flag)
{
getline(cin,line);
str+=line+'\n';
// vc++ 6.0 have a bug in include file: STRING. You shoud fix it.
//Or you shoud press ENTER more than twice to terminate inputing.
//Replace I.rdbuf()->snextc(); to _I.rdbuf()->sbumpc();
if(line.empty())
flag=false;
}
// get the length n
iss.str(str);
while(iss>>x)
{
n++;
}
double *v=new double[n];
iss.clear();// very important.
// initialize v[n]
iss.str(str);
for(i=0;i<n;i++)
iss>>v[i];
// output v
for(i=0;i<n;i++)
{
cout<<v[i];
if(i<n-1)
cout<<' ';
}
cout<<endl;
delete []v;
}