swapping string in c using pointer - c

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')

Related

String concatenation in C?

I am trying to understand string's behavior in C and it is bothering me since my following two code snippets result into different output:
(For the sake of this question, Let us assume user enters 12)
int main(void)
{
char L_Red[2];
char temp[] = "I";
printf("Enter pin connected to red: ");
scanf("%s", L_Red);
strcat(temp,L_Red);
printf("%s \n", temp);
return 0;
}
this yields: 12 as output (and not I12) Why ?
int main(void)
{
char L_Red[2];
printf("Enter pin connected to red: ");
scanf("%s", L_Red);
char temp[] = "I";
strcat(temp,L_Red);
printf("%s \n", temp);
return 0;
}
This yields: I12I (and not, I12) Why ?
I have read about string in C and as per my understanding, neither am I allocating temp any fixed size and changing it later to get these vague outputs nor am I using strings like the way they are not supposed to. Is there any other concept at play here ?
The array temp is an array of two characters (the 'I' and the string terminator '\0'). That's it. Attempting to append more characters to that array will write out of bounds and lead to undefined behavior.
You need to make sure that the destination array temp have enough space to fit its original content plus the string you want to append (plus the terminator).
Also, if you want to input more than one character for the "string" L_Red you need to increase its size as well.
I also recommend you use a limit in the format specifier so you can't write out of bounds:
char L_Red[3]; // Space for two characters, plus terminator
scanf("%2s", L_Red); // Read at most two characters of input
You are getting strange answers because your destination string (ie the first argument to strcat) is not long enough to handle both strings plus a null termination character. Also the length of L_Red is too short as it does not have enough space for the null termination character either.

Given a string write a program to generate all possible strings by replacing ? with 0 and 1?

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.

Tokenizing a phone number in C

I'm trying to tokenize a phone number and split it into two arrays. It starts out in a string in the form of "(515) 555-5555". I'm looking to tokenize the area code, the first 3 digits, and the last 4 digits. The area code I would store in one array, and the other 7 digits in another one. Both arrays are to hold just the numbers themselves.
My code seems to work... sort of. The issue is when I print the two storage arrays, I find some quirks;
My array aCode; it stores the first 3 digits as I ask it to, but then it also prints some garbage values notched at the end. I walked through it in the debugger, and the array only stores what I'm asking it to store- the 515. So how come it's printing those garbage values? What gives?
My array aNum; I can append the tokens I need to the end of it, the only problem is I end up with an extra space at the front (which makes sense; I'm adding on to an empty array, ie adding on to empty space). I modify the code to only hold 7 variables just to mess around, I step into the debugger, and it tells me that the array holds and empty space and 6 of the digits I need- there's no room for the last one. Yet when I print it, the space AND all 7 digits are printed. How does that happen?
And how could I set up my strtok function so that it first copies the 3 digits before the "-", then appends to that the last 4 I need? All examples of tokenization I've seen utilize a while loop, which would mean I'd have to choose either strcat or strcpy to complete my task. I can set up an "if" statement to check for the size of the current token each time, but that seems too crude to me and I feel like there's a simpler method to this. Thanks all!
int main() {
char phoneNum[]= "(515) 555-5555";
char aCode[3];
char aNum[7];
char *numPtr;
numPtr = strtok(phoneNum, " ");
strncpy(aCode, &numPtr[1], 3);
printf("%s\n", aCode);
numPtr = strtok(&phoneNum[6], "-");
while (numPtr != NULL) {
strcat(aNum, numPtr);
numPtr = strtok(NULL, "-");
}
printf("%s", aNum);
}
I can primarily see two errors,
Being an array of 3 chars, aCode is not null-terminated here. Using it as an argument to %s format specifier in printf() invokes undefined behaviour. Same thing in a differrent way for aNum, too.
strcat() expects a null-terminated array for both the arguments. aNum is not null-terminated, when used for the first time, will result in UB, too. Always initialize your local variables.
Also, see other answers for a complete bug-free code.
The biggest problem in your code is undefined behavior: since you are reading a three-character constant into a three-character array, you have left no space for null terminator.
Since you are tokenizing a value in a very specific format of fixed length, you could get away with a very concise implementation that employs sscanf:
char *phoneNum = "(515) 555-5555";
char aCode[3+1];
char aNum[7+1];
sscanf(phoneNum, "(%3[0-9]) %3[0-9]-%4[0-9]", aCode, aNum, &aNum[3]);
printf("%s %s", aCode, aNum);
This solution passes the format (###) ###-#### directly to sscanf, and tells the function where each value needs to be placed. The only "trick" used above is passing &aNum[3] for the last argument, instructing sscanf to place data for the third segment into the same storage as the second segment, but starting at position 3.
Demo.
Your code has multiple issues
You allocate the wrong size for aCode, you should add 1 for the nul terminator byte and initialize the whole array to '\0' to ensure end of lines.
char aCode[4] = {'\0'};
You don't check if strtok() returns NULL.
numPtr = strtok(phoneNum, " ");
strncpy(aCode, &numPtr[1], 3);
Point 1, applies to aNum in strcat(aNum, numPtr) which will also fail because aNum is not yet initialized at the first call.
Subsequent calls to strtok() must have NULL as the first parameter, hence
numPtr = strtok(&phoneNum[6], "-");
is wrong, it should be
numPtr = strtok(NULL, "-");
Other answers have already mentioned the major issue, which is insufficient space in aCode and aNum for the terminating NUL character. The sscanf answer is also the cleanest for solving the problem, but given the restriction of using strtok, here's one possible solution to consider:
char phone_number[]= "(515) 555-1234";
char area[3+1] = "";
char digits[7+1] = "";
const char *separators = " (-)";
char *p = strtok(phone_number, separators);
if (p) {
int len = 0;
(void) snprintf(area, sizeof(area), "%s", p);
while (len < sizeof(digits) && (p = strtok(NULL, separators))) {
len += snprintf(digits + len, sizeof(digits) - len, "%s", p);
}
}
(void) printf("(%s) %s\n", area, digits);

C programming : Strings

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

String is adding special characters

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.

Resources