Segmentation fault(SIGSEGV) in my code - c++

Im getting Segmentation fault(SIGSEGV) for many problems that iv solved in spoj and other websites. Im giving the problm statement link and code. Can anybody tell me the mistakes that iv done below.
Problem :
http://goo.gl/CVROl
Thanks in advance.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
char a;
string final,dummy;
int t,h,p,k,z;
scanf("%d",&t);
while(t)
{
cin>>a>>h>>p;
final=a;
for(int i=0;i<h;i++)
{
k=0;
for(int j=0;final[j]!='\0';j++)
{
if(final[j]=='a')
{
dummy[k]='a';
dummy[k+1]='b';
k+=2;
}
else
{
dummy[k]='b';
dummy[k+1]='a';
k+=2;
}
}
final=dummy;
}
printf("%c\n",final[p-1]);
t--;
}
return 0;
}

As pointed out by sstn, you did not allocate memory for dummy. Since it's a string and it looks like you just want to append characters to it, you can do:
for(int j=0;j < final.size();j++)
{
if(final[j]=='a')
{
dummy.push_back('a');
dummy.push_back('b');
}
else
{
dummy.push_back('b');
dummy.push_back('a');
}
}
final=dummy;

final is of type std::string, which aren't null terminated.
In your for loop: for(int j=0;final[j]!='\0';j++) you're checking for the end of the string as you would do in C (which a char* -- null terminated string), but in C++ you should iterate over string characters in some other ways: using an iterator, counting up the string size or something.
A fast quick to this problem (don't know whether there are others) is to get the null terminated char* representation of final: final.c_str() and iterater over it as you're doing.

Related

Removing a specific element from a string in C++

I was trying to remove X from a given string, the code compiles and runs but there is no output shown. I guess the problem is where I have to use the 'cout' operator.
Here is my Code:
#include<iostream>
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
void removeX(char str[])
{
if(str[0]='\0')
{
cout<<str;
}
if(str[0]!='x'||str[0]!='X')
{
removeX(str+1);
}
else
{
for(int i=0;i!='\0';i++)
{
str[i]=str[i+1];
}
removeX(str+1);
}
}
int main()
{
char a[]="MALCOLM X";
removeX(a);
return 0;
}
You have a few issues in your code, the ones I can spot right away are:
if(str[0]='\0') - this is an assignment, not a comparison. Your entire string will be replaced with \0-characters - no characters will be skipped because this:
if(str[0]!='x'||str[0]!='X') is always true. Ask yourself if x is different from x (false) OR X (true). False or true = true.
The check should be implemented something like (str[0] != 'x' && str[0] != 'X').
Edit: One more issue.
The overall logic will not work (-ish). The part where you run through the string and compress it is correct enough. But you try to run to the end and then print the string, however at that point you are only holding the end of the string (the null termination), so no matter what else you have done you will only print that (aka. print nothing).
Instead, once you are done compressing the xs out of the string, you need to return to the beginning of the string and then print that. The easy way is to print in main, or you can split your function into an outer+inner function like:
void outer_removeX(str) {
removeX(str);
print(str);
}
Or you could add an extra variable to the recursion that allows you to return to the first call in the chain and then print there.
However, only printing the end will not work.
try the following code:
#include<iostream>
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
void removeX(char str[],int j)
{
if(str[j]=='\0')
{
cout<<str;
}
else if(str[j]!='x' && str[j]!='X')
{
removeX(str,++j);
}
else
{
for(int i=j;str[i]!='\0';i++)
{
str[i]=str[i+1];
}
removeX(str,j);
}
}
int main()
{
char a[]="MAxLCOLM X";
removeX(a,0);
return 0;
}

scanf for both character and integer

I am trying to take input character and integer both. But when i use cin>>ch>>val; for taking input,it works.But Using scanf("%c%d",&ch,&val);,it shows me run time error.What can i do to get rid of this problem? I want to use scanf for faster input.
Here is my partial code:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int q;
scanf("%d",&q);
while(q--)
{
char ch;
int val,in;
//cin>>ch>>val;
scanf("%c %d",&ch,&val);
in=val;
if(ch=='a'){
//scanf("%d",&val);
//update(1,0,m,++indx,val);
printf("First Case\n");
}else{
//si(in);
//if(in>tree[1]) printf("none\n");
//else query(1,0,m,in);
printf("Second Case\n");
}
}
}
I ran this code! It works fine for me. So probably you're using scanf in C++ and forgot to include or maybe it's something else with your code.
Can you share the full code. There is no issue with scanf() function as you have mentioned. You can take multiple inputs like scanf(%d%d%c%c,&a,&b,&c,&d);
#include <stdio.h>
int main()
{
printf("Hello World");
int q=1;
while(q--)
{
char ch;
int val,in;
scanf("%c%d",&ch,&val);
in=val;
if(ch=='a'){
printf("%d",val);
}else{
printf("%d",val);
}
}
return 0;
}

Character replacement not working

enter image description hereI have the following code that is supposed to replace instances of pi (3.14) with the word "pi". For example, "x3.14 3.14 3.14xx" should be turned into "xpi pi pixx". However, my code isn't doing that; why doesn't it work, and how would I fix it?
#include<iostream>
#include<cstring> //dsfsdf
#include<string>
#include<cstdio>//sdfdsf
using namespace std;
void replacepi(char *arr,int i)
{
//base
if(arr[i]=='\0')
{
cout<<arr<<endl;
return;
}
//recc
if(arr[i]=='3' && arr[i+1]=='.' && arr[i+2]=='1' && arr[i+3]=='4')
{
arr[i]='p';
arr[i+1]='i';
for(int j=i+4;arr[j]!='\0';j++)
arr[j-2]=arr[j];
arr[strlen(arr)-2]='\0';
}
replacepi(arr,i+1);
}
int main() {
long int n;
cin>>n;
for(int i=0;i<n;i++)
{
char arr[1000];
cin.getline(arr,sizeof(arr));
replacepi(arr,0);
}
return 0;
}
Looks like a job for regex_replace. Given you've read your input into arr you can just dump the replacement to the console like this:
regex_replace(ostream_iterator<char>(cout), cbegin(arr), cend(arr), regex("3\.14"), "pi")
Live Example
Naturally arr should be a string as in the example rather than a char[], as given any size char[] the input may be larger, a string will always work.

Garbage values are printing even after null character

This code is for printing left recursion alternatives in a production.But when printing alternatives at last garbage values are being added.Why am i getting such error?
how to resolve such problem?in the image the output is displayed.but that is the wrong output
#include<iostream>
#include<cstring>
using namespace std;
class production
{
private:
char lhs;
char rhs[10][10],lr[10][10];
int noa;
public:
production()
{
noa=0;
}
void makeprod(char *str)
{
lhs=str[0];
char r[20];
strcpy(r,str+3);
int j=0;
for(int i=0;r[i]!='\0';i++)
{
if(r[i]!='/')
rhs[noa][j++]=r[i];
else
{
rhs[noa++][j]='\0';
j=0;
}
}
noa++;
}
void checkLR()
{
int ct=0,m=0;
for(int i=0;i<noa;i++)
if(lhs==rhs[i][0])
{
strcpy(lr[m],rhs[i]);
m++;
ct++;
}
if(ct>0)
{
for(int k=0;k<ct;k++)
cout<<"Left recursion at "<<lr[k]<<"\n";
}
else
cout<<"no\n";
}
void printprod()
{
cout<<"LHS = "<<lhs<<"\n";
cout<<"RHS = ";
for(int i=0;i<noa;i++)
cout<<rhs[i]<<" ";
}
};
int main()
{
production p;
char str[20];
cout<<"enter a production\n";
cin>>str;
p.makeprod(str);
p.printprod();
p.checkLR();
return 0;
}
In makeprod you're checking your input string for / to add the termination character to your rhs-array, and thus your input string has to end with the / sign. You have several choices :
either initialize your arrays with 0, so the rhs-array is always null-terminated (independently from your question : It's always good practice to initialize your variables)
add a null-termination sign (0) to rhs when the end of your input string is reached
edit: Just place a memset(rhs, 0, sizeof(rhs)*sizeof(char)); (the same for lr) in your constructor and the output should be fine. This will initialize your arrays with zeroes and thus the string is null-terminated.
But you really should add some overflow checking.
You are propably incrementing noa one time too much in makeprod().
That makes the for loop in printprod() access rhs 1 element after its end.

reversing the letters of the words in a string

I want to reverse the letters of the words in a string and have to store it in the same array.example: i/p: hi how are you o/p: ih woh era uoy. i wrote this programs but it just prints the same string without reversing and the program is not terminating it continues to print something. i cant findout the mistake. please help me and tell me the correct code.
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void stre(char (&a1)[20], int j1, int i1)
{
char b[20];
for(int k=i1-j1;k<i1;k++)
b[k]=a1[i1-k-1];
for(k=i1-j1;k<i1;k++);
a1[k]=b[k];
}
void main()
{
clrscr();
int j;
char a[20];
gets(a);
for(int i=0;a[i]!='\0';i++)
{
j++;
if(a[i]==' ')
{
stre(a,j,i);
j=0;
}
}
stre(a,j,i);
for(j=0;j<i;j++)
cout<<a[j];
getch();
}
friends after your answers i removed the semicolon in the for loop and also initialized j=0 but still i am not able to get the required output now for the i/p:hi how are you o/p:ihh hi hhi hhi. still need your help.
for(k=i1-j1;k<i1;k++);
a1[k]=b[k];
The semilcolon after the for loop prevents the last action from occuring multiple times.
try
#include <iostream>
using namespace std;
int main() {
int j =0;
char a[20] = "hi how are you";
char b[20] = "";
int l=0;
for(int i=0;a[i]!='\0';i++){
if(a[i]==' ' ||a[i+1]=='\0'){
cout<<j<<' '<<i;
if(a[i+1]=='\0'){
b[l++] = ' ';
}
for(int k=i;k>=j;k--){
b[l]=a[k];
l++;
}
for(int k=j;k<=i;k++){
cout<<b[k];
a[k] = b[k];
}
cout<<endl;
j = i+1;
}
}
cout << a;
return 0;
}
This for loop is terminated by the semi-colon:
for(k=i1-j1;k<i1;k++);
^^^
Here's a version that is not perfect by any means, but at least, it tries to be more like C++ than C:
http://ideone.com/f5vciW
first: tokenize into words and space sequences
//the spaces should be preserved
std::string test("hi how are you"),reference("ih woh era uoy");
std::vector<std::string> tokens;
tokenize(test,tokens);
then reverse the tokens
for (auto& token : tokens)
std::reverse(token.begin(),token.end());
assemble tokens into a string buffer
std::stringstream buf;
for (auto token : tokens)
buf<<token;
check the result
std::string res=buf.str();
assert(res==reference);
where the tokenizer looks like that:
template <typename TContainer,typename TString>
void tokenize(TString input,TContainer& res)
{
if (input.length()<2) {
res.push_back(input);
return;
}
typename TString::const_iterator pos=input.begin();
bool space_state=std::isspace(input[0],std::locale());
for (typename TString::const_iterator it=input.begin(); it!=input.end();
++it) {
bool is_space=std::isspace(*it,std::locale());
if (is_space!=space_state) {
res.push_back(TString(pos,it));
pos=it;
space_state=is_space;
}
}
//the rest
if (pos!=input.end()) {
res.push_back(
TString(
pos,
static_cast<typename TString::const_iterator>(input.end())
));
}
}
you passed j without assigning the value. so it will be garbage.
I can see two things in your code that may not result in the expected output:
1)
int j;
should be replaced with
int j=0;
And
for(k=i1-j1;k<i1;k++);
a1[k]=b[k];
the semicolon after the for loop needs to be removed.
FYI, this mixing of C and C++ code is not recommended (it's compromising readability). please stick to either one of them.
A similar example is shown on this site. They've also used almost the same approach that you'v e chosen(reversing each word by counting number of spaces) by with the help of stack data structure.
Make sure you have the STL library installed in your environment to run this code. Better run this code on linux platform.
Here's another, shorter version, doing the inversion in-line without using an extra buffer:
http://ideone.com/hs9NZ7
the criterion for the tokenizer is the change in the isspace condition:
auto next_token=
[&](char c) {
return std::isspace(c,loc)!=std::isspace(*pos,loc);
};
using that we can go through the input string and visit the tokens:
for (auto it=std::find_if(pos,test.end(),next_token);
it!=test.end();
it=std::find_if(pos,test.end(),next_token))
reversing them and updating the current position
std::reverse(pos,it);
pos=it;
and not forgetting the leftover token.