Swap strings using strcpy - c

I am trying to swap two strings by using only pointer notation, (no arrays), with
a function that looks like this
void str_switch(char *a, char *b)
the swapping should work irrespective of the sizes of b and a, and it is not known.
my idea is this:
void str_switch(char *a, char *b) {
const char *temp = a;
strcpy(b, temp);
}
however, after this, I am not sure how to copy b to a, because b changes, I tried declaring other constant pointers, but once I change b, I can never get the old version.

This strays from your question, heading in particular as strcpy is not used, and follow your comment to Martin James:
void str_switch(char **a, char **b) {
char *tmp = *a;
*a = *b;
*b = tmp;
}
If you really want to use strcpy you'll have to know size of C-strings.

if your strings are stored in allocated memories using functions like malloc(); thus this code works perfectly for that case, especially as it treats strings with different size and length
#include <stdio.h> // list of libraries that need to be included
#include <stdlib.h>
#include <string.h>
void str_switch(char **a, char **b) {
if (strlen(*a)>strlen(*b)) // check the strings with lowest size to reallocate
{ // in order to fit the big one
char *temp=malloc((strlen(*a)+1)*sizeof(char)); // temp variable to preserve the lowest
// the variable with lowest length
strcpy(temp,*a); // store the longest string in its new location
strcpy(*a,*b);
free(*b); // free the allocated memory as we no longer need it
*b=temp; // assign the new address location for the lowest string
}
else if (strlen(*b)>strlen(*a)) // the same as above but invert a to b and b to a
{
char *temp=malloc((strlen(*b)+1)*sizeof(char));
strcpy(temp,*b);
strcpy(*b,*a);
free(*a);
*a=temp;
}
else // if the lengths are equal ==> #Morpfh solution
{
char *tmp = *a;
*a = *b;
*b = tmp;
}
}
This is a test for function above (main code)
int main(int argc, char *argv[])
{
char *a=malloc(sizeof(char)*6);
strcpy(a,"hello");
char *b=malloc(sizeof(char)*4);
strcpy(b,"bye");
printf("a=%s\nb=%s\n",a,b);
str_switch(&a,&b);
printf("----------------------\n");
printf("a=%s\nb=%s\n",a,b);
return 0;
}
and we get
a=hello
b=bye
----------------------
a=bye
b=hello

If you don't want to allocate extra storage, you would need to switch the strings by swapping one character at a time.
If you are OK allocating extra storage, strdup a, strcpy b into a, strcpy the copy of a into b, then free the copy.

Related

Don't know how to define my swap function properly

I can understand pointers to a certain extent but the multiple layers of dereferencing in swap() is confusing me. Thus,I'm unable to implement it correctly.
Below is a code on alphabetizing based on insertion sort:
void insertionSort(char **array,int rows,int cols)
{
for(int i=1;i<=rows-1;i++)
{
for(int j=i-1;strcmp(array[i],array[j])<0 && j>=0;j--)
{
swap(&array[i],&array[j]);
i--; //when swapped, subscript of key also drops
}
}
}
void swap(char **s1,char**s2)
{
char **temp=s1;
strcpy(*s1,*s2);
strcpy(*s2,*temp);
}
I know the swap() is wrongly implemented. I hopefully would like to know how to step through the thinking process to correctly implement swap()(ie how to understand the muliple layers of dereferencing better)
You don't want to use strcpy at all. You simply want to swap two char *s, to which you have pointers (char **s). As such, the implementation should be the same as any other swap. The temporary should be a char *, and you should be swapping the char * values, not copying the strings that lie behind them.
void swap(char **s1,char **s2)
{
char *temp = *s1;
*s1 = *s2;
*s2 = temp;
}
This is exactly the same as e.g. a function for swapping ints, except with int replaced by char *.

Generic type swap c function

I am trying to write a simple function that will swap any two variables of the same of type.
void swap(void* a, void* b, int size);
void swap(void* a, void* b, int size){
void* temp = malloc(size);
memcpy(temp, a,size);
memcpy(a, b, size);
memcpy(b, temp,size);
free(temp);
}
int main(int argc, char* argv[])
{
char name[] = "name";
char greet[] = "greet";
swap(name, greet, 30);
printf("%s\n", name);
printf("%s\n", greet);
return 0;
}
But what the above code prints is:
`
name
The value of pointed to by a (in swap) changes to ` after memcpy(b, temp, size), I am unsure why?
When you call memcpy(b, temp,size); with size being equal to 30 and the actual size of the string pointed by b being 6, you basically write past the memory you own.
In your case, your program will actually damage the program stack. If in memory b comes before a the additional 24 will effectively rewrite the contents of a completely.
You have to check whether the size is less than or equals the least size of the both strings + 1 (to account for the null character).
There are some bugs, resulting in undefined behavior.
1. You are copying 30 bytes from an array, which is 5 bytes long ("name" is 4 chars + 1 byte of trailing 0).
2. You are copying 30 bytes to array, which is 6 bytes long ("greet" is 5 chars + 1 byte of trailing 0).
Both bugs can cause the problem, especially the second one: you are trying to use 24 bytes of memory over array bounds - it is not possible to determine the results of this.
As someone wrote in comments, the better way will be exchanging the pointers, nor pointed bytes.
As noted by the comments, you cannot swap greet and name, as their types do not match: char[6], vs char[5] (including terminating NUL), and they have different size.
However, the swap can be used on char * object, since char array can be converted to char *, the change is simple.
int main(int argc, char* argv[])
char name[] = "name";
char greet[] = "greet";
char *p1 = name ;
char *p2 = greet ;
swap(&p1, &p2, sizeof(p1)) ;
printf("%s\n", p1);
printf("%s\n", p2);
}
Side note: No need to use malloc for the temp space, unless you are expecting to move very large objects. Just char temp[size] ; will do the work - instead of malloc - and no need to free (and minor performance gain).

How I can make a string array interchange it's components with a swap function?

The problem is that this code won't interchange these 2 strings. I'm new to programming but I can tell that the problem is that swap function, but I do not know how to fix it.
I tried to add strcpy instead of "=" in swap but that didn't worked.
#include <stdio.h>
#include <stdlib.h>
void swap(char *t1, char *t2) {
char *t;
t=t1;
t1=t2;
t2=t;
}
int main() {
char *s[2] = {"Hello", "World"};
swap(s[0], s[1]);
printf("%s\n%s", s[0], s[1]);
return 0;
}
You want to use out parameters here, and since your strings are represented as pointers, you need pointers to pointers:
void swap(char **t1, char **t2) {
char *t;
t = *t1;
*t1 = *t2;
*t2 = t;
}
Call it like this:
swap(&s[0], &s[1]);
I tried to add strcpy instead of "=" in swap but that didn't worked.
The reason why that doesn't work is because the strings are actually stored in the program's binary and therefore can't be modified, and with strcpy you would write over them. If you copy them to the stack or the heap instead then you can do the swap with strcpy. Of course that's going to be less efficient than just swapping the pointers, but this is how it would look like:
void swap(char *t1, char *t2) {
char buf[16]; // needs to be big enough to fit the string
strcpy(buf, t1);
strcpy(t1, t2);
strcpy(t2, buf);
}
Also you would need to change the definition of s to something akin to
char s[2][16] = { "Hello", "World" }; // strings are copied to the stack now
Check the types carefully.
What you have got as array members are pointers (to the starting element of string literals). You need to swap the members in a way so that they point to the other string literal. So, you need to change those pointers themselves.
So, you need to pass pointer to those pointers and then make the change from the called function.
Do something like
swap(&(s[0]), &(s[1]));
and then, in the called function:
void ptrSwap(char **t1, char **t2) {
char *temp;
temp=*t1;
*t1=*t2;
*t2=temp;
}
Bonus points: Name your functions (and variables, too, wherever applicable) meaningfully.
You need to passing the pointer of pointer, i.e. address of the position in array where the strings are present, so that you can swap and place correct addresses there.
Try the below code:
#include <stdio.h>
#include <stdlib.h>
void swap(char **t1, char **t2) {
char *t;
t=*t1;
*t1=*t2;
*t2=t;
}
int main() {
char *s[2] = {"Hello", "World"};
swap(&s[0], &s[1]);
printf("%s\n%s", s[0], s[1]);
return 0;
}
Output:
World
Hello

Xcode Exc_BAD_ACCESS

so this code is giving me the Exc_bad_access_code(2) error and i have no idea why. I think the problem is with the parameters but im not sure, any thoughts?
#include <stdio.h>
void swap(char *x, char *y);
/* Function to swap values at two pointers */
void swap(char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
int main(int argc, const char * argv[]) {
// insert code here...
char *a = "ASD123";
swap (a+1 , a+2);
return 0;
}
You need to post the complete crash log to be sure, but it's probably that you are attempting to manipulate a string constant:
char *a = "ASD123";
swap (a+1 , a+2);
which probably lives in read-only memory.
Try:
char a[12];
strcpy(a, "ASD123");
swap (a+1 , a+2);
or:
char a[] = "ASD123";
swap (a+1 , a+2);
That will copy the string onto the stack, where it may be modified without issue. You could also use strdup() to copy the string onto the heap (don't forget to call free() to release the allocated memory).
You are trying to modify a string literal.
Change
char *a = "ASD123";
to
char a[] = "ASD123";
and your program will work.
In the first case a is simply a pointer pointing to a string literal which is in a write protected part of the memory on most platforms, hence the crash because you try to write info write protected memory.
In the second case a is a char array of length 7 which is initialized with "ASD123" (6 chars for the string and one char for the terminating zero).
You need to initialize a correctly. Something like char a[7] = "ASD123";
char* a only creates a pointer-to-char, it does not allocate enough memory to store the characters.

My own strcpy function

As a learning technique, i'm suppose to make my own copy of the following string function in
char * mystrcpy(char *a, char *b);
// string copy. destroys a but not b.
// identical to strcpy in <string.h>
// running time O(mystrlen(b))
I've come with this
char * mystrcpy(char *a, char *b){
a = b;
return a;
}
since string a is a random chuck in memory I'm thinking to assign just to string b ... is my interpretation correct ?
accessing a specific char [in index i] in string is done using a[i], just like an array. [remember that in C, a string is actually an array of chars].
You should iterate the strings until you "see" a '\0' char - which indicate the end of string.
Yes, comparing to chars with operator< is comparing them by their ascii value - which is probably what you need.

Resources