I am trying to replace a word within a sentence with another word.
For ex. if str1="strong" and str2="weak", then the 1st string in str should get changed to "If the core is weak, you can't go wrong".
I am getting segmentation fault(core dumped) error.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void func(char *str,char *str1,char *str2,int l1,int l2)
{
int i,m,j,c;
for(i=0;*(str+i)!='\0';i++)
{
if(*(str+i)==*str1)
{
for(m=i,j=0;j<l1;m++,j++) /*checking the equality of the two words*/
{
if(*(str+m)!=*(str1+j))
break;
else
c=1;
}
if(c==1)
{
for(j=i;*(str+j)!='\0';j++)
*(str+j+l2-l1)=*(str+j);
for(m=0,j=i;(*(str2+m)!='\0');j++,m++)
*(str+j)=*(str2+m);
}
}
}
}
int main()
{
char *str[]={
"If the core is strong, you can't go wrong",
"Canada's wonder of the world",
"Processing a sorted array",
"Was that a joke?",
"I wanna be a millionaire",
"Your post is not properly formatted"
};
int i,l1,l2,k,j;
char str1[10],str2[10];
l1=strlen(str1);
l2=strlen(str2);
printf("Enter string 1 : ");
scanf("%s",str1);
printf("\nEnter string 2 : ");
scanf("%s",str2);
for(k=0;k<=5;k++)
func(str[k],str1,str2,l1,l2);
for(i=0;i<6;i++)
{
printf("\n");
for(j=0;*(str[i]+j)!='0';j++)
printf("%c",*(str[i]+j));
}
return 0;
}
char *str[]={
"If the core is strong, you can't go wrong",
"Canada's wonder of the world",
"Processing a sorted array",
"Was that a joke?",
"I wanna be a millionaire",
"Your post is not properly formatted"
};
This creates a array of character pointers and each pointer points to a string literal and if you modify a string literal it will result in segmentation fault since it is in read-only memory. this is the reason that you are getting segmentation fault.
Do check your logical errors too in your code.
Your code is unfortunately wrong on many levels. Others have already pointed out the string literal issue, and the issue with strlen() before scanf() in main(), but there is more wrong:
1. You try to edit the string in-place. What happens if you replace a sub-string with a longer string? You try to move the string forward. But that means you write past the end of the memory allocated to the string. This is undefined behaviour and may crash.
2. In func():
[snip]
if(c==1)
{
for(j=i;*(str+j)!='\0';j++)
*(str+j+l2-l1)=*(str+j);
for(m=0,j=i;(*(str2+m)!='\0');j++,m++)
*(str+j)=*(str2+m);
}
You iterate until the source string is null-terminated, but you don't copy the null-terminator! Later on, you try to printf() the string (character by character, for some unfathomable reason, also not checking for a null-terminator but for an ASCII '0'...), which will then crash due to the lack of null-termination.
To solve your issues, you can do the following:
1. Walk through the string using strstr() to find the sub-string to replace. Count the number of occurrences of the sub-string.
2. Use strlen() in func() to determine the length of the sub-string and the replacement. Multiply the difference by the number of occurrences of the sub-string to find how much longer or shorter your new string will be. Add the difference to strlen() of the original string to find out how much memory to allocate (Remember to allocate an extra byte for null-termination).
3. Allocate the needed memory with malloc().
4. Use a combination of strcpy()/strncpy()/memmove()/strstr()/whatever standard library functions you need to assemble your new string.
Related
I have written this code it is working fine for a?b?c? and a?b?c?d? but for a?b?c?d?e? it is giving one additional garbage value at the end. At the end of s there is '\0' character attached then why and how is it reading that garbage value. I tried to debug it by placing printf statements in between the code but couldn't resolve it. please help.
#include<stdio.h>
void print(char* s,char c[],int l)
{
int i,j=0;
for(i=0;s[i]!='\0';i++)
{
if(s[i]=='?')
{
printf("%c",c[j]);
j++;
}
else
printf("%c",s[i]);
}
printf(", ");
}
void permute(char *s,char c[],int l,int index)
{
if(index==l)
{
print(s,c,l);
return;
}
c[index]='0';
permute(s,c,l,index+1);
c[index]='1';
permute(s,c,l,index+1);
}
int main()
{
char s[10],c[10];
printf("Enter a string.");
scanf("%s",s);
int i,ct=0;
for(i=0;s[i]!='\0';i++)
{
if(s[i]=='?')
ct++;
}
permute(s,c,ct,0);
return 0;
}
My output was like this :-
a0b0c0d0e0♣, a0b0c0d0e1♣,
...and so on.
As we can see from your code, with an array defined like char s[10] and the input being
a?b?c?d?e?
is too big an input to be held in s along with the null-terminator by
scanf("%s",s);
You need to use a bigger array. Otherwise, in attempt to add the terminating null after the input, the access is being made to out-of-bound memory which invokes undefined behaviour.
That said, never allow unbound input to the limited-sized array, always use the field-width to limit the input length (in other words, reserve the space for null-terminator), like
scanf("%9s",s);
The code is producing the correct output here, but note that it has undefined behavior for strings of size greater than or equal to 10 chars, because that's the size of your buffer.
So, for a?b?c?d?e? you need a buffer of at least 11 characters, to account for the null terminator. You should make s bigger.
See actually in C what happens in String is that everytime it appends a '\0' character at last.
Now notice in C there is nothing called string.
It's array of characters.
So if you have defined like this-
char s[10]
This actually accepts an array of less than of 9 characters as the last one will be the '\0' character.
If you add more than 9 character it will give erroneous output.
My problem is: Input the string then replace the word that we want to change
For example: input: i love coke
word: coke
replace: pepsi
result: i love pepsi
But when i run this code it crashed. Can you help show me the mistake?
#include <stdio.h>
#include<string.h>
char replace(char s1[100],char s2[100],char s3[100])
{
int k,i,j;
for(i=0;i<strlen(s1);i++)
for(j=0;j<strlen(s2);j++)
for(k=0;k<strlen(s3);k++)
{
if(s1[i]==s2[j])
{
s1[i]=s3[k];
}
}
return s3;
}
int main()
{
char s1[100],s2[100],s3[100];
printf("input string: ");gets(s1);
printf("Find string: ");gets(s2);
printf("Replace: ");gets(s3);
printf("Result: %s",replace(s1,s2,s3));
return 0;
}
I suggest you use a 4th buffer to store the generated result. You won't be able to replace locally if the word to be replaced and the new word aren't the same length.
Also, you are comparing characters individually. Just because you found a c doesn't automatically mean you found coke and that you should replace it. You must check the entire word is there before replacing anything. Use strstr() to locate substrings inside a string.
In addition, your function is returning a char, it should return a string (char *).
Furthermore, there are plenty of examples online on how to write a function to replace words on a string, so lets not be reduntant. Google it.
Strings in C are null terminated e.g. "i love coke\0". The string length does not include the null terminator. Because of this you are overwriting the null terminator after the 'e' with the 'i' in "pepsi".
A quick hack to check if null terminating the string would help, is to memset s1, s2, and s3 to 0.
Your approach doesn't quite work. What you need to do is search the input string for the word you wish to replace. So, before you even start switching things around, you need to search for the whole word you wish to replace.
Once you find that word, you need to then put in your new word in it's place, and then start searching for the word again untill you finish your input string.
So, for pseudo code:
for i in input //for every letter
if input[i] != lookfor[0]
results[i] put input[i] into new "results" array
else // We might have found it.
for j in lookfor // Go through coke, one at a time
if input[i+j] != lookfor[j] "c,o,k,e"
break; //You didn;t find coke, just "c" or "co" or "cok"
// If you got all the way through, you found coke.
//So now you have to switch that out for the new that in the result
results[i] = "pepsi" //Just be careful here, because this has a different index than i, because pespi's length != coke's length
Did that make sense?
First of all, your replace function is returning to char instead of char*. You can also define your function's return type as void and can make it return to char* buffer (in/out) parameter after in-function string operations. Moreover, you can use strtok(), strcmp() and strstr() predefined string.h functions to accomplish any kind of string operations.
Check this out to get information about standart string operation functions: String Operations
I started following tutorials on C, and then I (from scratch) attempted to do a program where the program chooses a word and you have to guess letters, until you find out the word or run out of attempts.
But I am stuck at the string part, really weird :
srand(time(NULL));
char pWord[6][15] = {"chocolate","peanut","bowling","helicopter","school","controller"}; // Possible words
int repeat=0;
int rNum = rand()%6;
char solution[strlen(pWord[rNum])];
while(repeat<strlen(pWord[rNum])) {
solution[repeat]=pWord[rNum][repeat];repeat++;
}
printf("Answer : %s", solution); printf("\n");
printf("R Answer : %s", pWord[rNum]); printf("\n");
printf("R length : %i", strlen(pWord[rNum])); printf("\n");
strcpy(solution,pWord[rNum]);
For bowling it is fine, but for others it adds weird special characters at random.
I have no idea why this is happening ( i come from java, somewhere lazy and easy ).
In C, the string ends with null character '\0'. So when you declare the character string solution, you need to add one to the length of the char array since strlen() function doesn't count the null character at the end.
char solution[strlen(pWord[rNum])+1];
Then after the while loop, you need to assign the '\0' to the last element of the char array:
while(repeat<strlen(pWord[rNum])) {
solution[repeat]=pWord[rNum][repeat];
repeat++;
}
solution[repeat]='\0';
A better way to do this string copying is to use strcpy() function instead of the while loop:
strcpy(solution, pWord[rNum]);
This way you don't have to assign the null character to the last character. This function does it for you.
Need help
this is my code
void swapstringfun()
{
int i=0,j=0;
char *str=(char *)malloc(sizeof(char)*15);
char *mystr=(char *)malloc(sizeof(char)*15);
system("cls");
printf("Please enter first string :\t");
scanf("%s",str);
printf("Please enter second string :\t");
scanf("%s",mystr);
while(*(str+i)!='\0' && *(mystr+i)!='\0')
{
*(str+i) ^=*(mystr+i);
*(mystr+i) ^=*(str+i);
*(str+i) ^=*(mystr+i);
i++;
}
printf("%s swapped to %s",str,mystr);
getch();
main();
}
I wrote the above code to swap the string using XOR operator. The problem with this code is. when my input is lets say.. RAJESH and ASHISH. Then, it shows output ASHISH and RAJESH. And, that is expected.
But, when input is let say.. ABHISHEK and CODER .Then, output is CODERHEK and ABHIS. But, the expected output is CODER and ABHISHEK. Anyone help me to solve this problem. I will appreciate.
You iterate and swap until you reach the end of the shorter string
while(*(str+i)!='\0' && *(mystr+i)!='\0')
(or both, if the lengths are equal). To iterate until you reach the end of the longer string, you need an || instead of the && and be sure that 1. both pointers point to large enough memory blocks, and 2. the shorter string ends with enough 0 bytes. So you should calloc the memory, not malloc.
However, you should swap the pointers, really,
char *tmp = str;
str = mystr;
mystr = tmp;
You also need to swap the terminating 0, as its part of what is called a string in C.
The 0 is the stopper element in the character array, describing the string.
You need to XOR the entire length of both strings. Since in your second example, the strings are different lengths, your algorithm won't work.
This is the statement you'll have to reconsider:
while(*(str+i)!='\0' && *(mystr+i)!='\0')
This is my source code:
#include <stdio.h>
#include <string.h>
void main()
{
int broj_znakova,i=0;
char niz1[81],niz2[81];
printf("Enter something, for end Ctrl/c \n\n");
while(fgets(niz1,81,stdin)!=NULL)
{
continue;
}
printf("You just enter: %s \n",niz1);
printf("This string is long %d\n",(strlen(niz1)-1));
strcpy(niz1,niz2);
printf("niz2 is %s\n",niz2);
if(strcmp(niz1,niz2)==0)
{
printf("niz1 and niz2 is same\n");
}
else
{
printf("niz1 != niz2\n");
}
while(niz1[i]!='\n')
{
if(niz1[i]==' ')
{
broj_znakova ++;
i=i+1;
}
}
printf("Spaces in string = %d\n",broj_znakova);
}
When i press Ctrl/c i got a bunch of strange characters, can someone help???
I google something about flushing but i'm new :)
The contents of niz2 is not initialized. It will result in undefined behavior. Perhaps you meant to copy niz1 to niz2. If so, then you need to reverse the parameters in the strcpy call. With strcpy, the first parameter is the target.
Note too that the variable broj_znakova is never initialized.
C does not "zero out" information in memory (in general) so when it allocates variables, you get whatever is there in memory at the time (whether it is logically readable as words or not), if you are printing something without the system knowing this is a string then it will keep printing until it encounters a NULL terminating character, if there is none, it tries to print whatever is in memory and this produces the weird characters.
On this line
strcpy(niz1,niz2);
I believe your parameters are reverse, it should be strcpy(niz2, niz1); The strange characters you are seeing is because niz2[81] has memory allocated, but it's not "filled in". So you get whatever 'magical' data that allocation may contain. That is, until you put something in it, or do memset, etc.