Swap char with table pointers in C - c

I'm trying to swap two char with two table pointers.
Can someone explain to me what's wrong in my code?
The terminal says char** is expected but I don't know what to do, so I think I don't really understand how pointers work for tables.
void echangeM2(char **ptab1, char **ptab2){
char *tmp = *ptab1;
*ptab1 = *ptab2;
*ptab2 = *tmp;
printf("%s\t %s",*ptab1,*ptab2);
return;
}
int main(void) {
char tab1[25];
char tab2[25];
char *adtab1;
char *adtab2;
*adtab1 = &tab1;
*adtab2=&tab2;
printf("type two words");
scanf("%s %s",tab1,tab2);
echangeM2(adtab1,adtab2);
return 0;
}

The following code should work for you:
#include <stdio.h>
void exchangeM2(char* *ptab1, char* *ptab2) { // accepts pointer to char*
char* tmp = *ptab1; // ptab1's "pointed to" is assigned to tmp
*ptab1 = *ptab2; // move ptab2's "pointed to" to ptab1
*ptab2 = tmp; // now move tmp to ptab2
printf("%s\t %s",*ptab1,*ptab2);
}
int main(void) {
char tab1[25];
char tab2[25];
char* adtab1;
char* adtab2;
adtab1 = tab1; // array name itself can be used as pointer
adtab2 = tab2;
printf("type two words");
scanf("%s %s",tab1,tab2);
exchangeM2(&adtab1, &adtab2); // pass the address of the pointers to the function
}

echangeM2(&adtab1,&adtab2);
This should fix the compile errors. You are passing char* pointers to a function that expects a char ** pointer
Edit: Actually looks like you want something like
char **adtab1;
char **adtab2;
adtab1 = &tab1;
adtab2=&tab2;
...
echangeM2(adtab1,adtab2);

Related

Access structure variables in a loop

My requirement is that i create a structure with variables like
struct stu{
char var_01;
char var_02;
.
.
char var_30;
}stu_t;
and not use an array instead like
char var[30];
With the above requirement established, i can't figure how to access these variables in a loop by concatenating var_ + iterating integer. I know i cant just concatenate, store in a variable and use that variable to access.
Appreciate any help. Thanks!
Variable names have no meaning at run-time in a C program. The names are only for humans, they are removed during compilation. That's why you can't build variable names and somehow use those.
The solution is to use an external array with pointers:
stu_t my_stu;
char * vars[30];
vars[0] = &my_stu.var_01;
vars[1] = &my_stu.var_02;
/* ... and so on ... */
Then you can use vars to access into my_stu:
*vars[0] = 'u';
printf("var_01 is '%c'\n", my_stu.var_01);
Of course this isn't very pretty, but that's what you get.
You can use a pointer for that:
struct stu{
char var_01;
char var_02;
/* ... */
char var_30;
}stu_t;
char* ptr = &stu_t.var_01;
while(ptr <= &stu_t.var_30)
{
*ptr = '0';
printf("Character #%ld = %c \n", ptr - &stu_t.var_01, *ptr);
ptr++;
}
You can use union but it's rather "ugly" hack and I wouldn't recommend it, but if you really want it... (Still, it requires using arrays somewhere! Union will make structure and array use the same location in memory.) Example:
#include <stdio.h>
union Test
{
struct
{
char var_00;
char var_01;
char var_02;
char var_03;
char var_04;
};
char var[5];
};
int main()
{
union Test t;
t.var_01 = 'a';
printf("%c\n", t.var[1]);
return 0;
}
It outputs a.
Anyway, it's better to simply use array. Your requirement is kind of weird...
If your structure only contains chars, you can do this:
typedef struct stu_s {
char a;
char b;
char c;
} stu_t;
int main()
{
stu_t my_struct;
char *ptr = (char *)(&my_struct);
ptr[0] = 1;
ptr[1] = 2;
ptr[2] = 3;
printf("%hhd %hhd %hhd\n", my_struct.a, my_struct.b, my_struct.c);
}

C simple string program does not compile

#include <stdio.h>
#include <string.h>
char Jones(char, char);
int main() {
char name[]="Andrew";
char surname[]="Jones";
char result[80];
result=Jones(name, surname);
puts(result);
return 0;
}
char Jones(char name, char surname)
{
char result[80];
int length;
length = strlen(surname);
for (int i=0; i<50; i++)
{
result[length+i] = name[i];
}
return result;
}
The program does not compile and i dont know why. It is supposed to read two strings and swap their places. It should display eg. "Jones Andrew".
Here's one problem:
char name[]="Andrew";
char surname[]="Jones";
char result[80];
wynik=Jones(name, surname);
This calls Jones() with character arrays (which will decay to character pointers), but the function is declared to accept single characters only.
You should change the function to take char *name, char *surname, since it really does seem to expect strings.
Further, you can't return a character array like you're doing in Jones(), you need to read up quite a bit on how to work with strings in C.
Also, wynik looks undeclared, that'll also make it fail to build.
There's a few errors:
char Jones(char, char);
This takes just a single char, not a char * which you need for a string.
result=Jones(name, surname);
Here result is an array. In C, you cannot assign to an array.
char Jones(char name, char surname)
{ char result[80];
...
return result;
}
Here you return result which is a local variable. But to return a string, you'd need to return a char*. But that char* would point to a local variable within the Jones function, which is no longer valid when the function ends. One solution is to pass in a buffer where you write the result that the caller owns.
Your algorithm for combining the surename and name is also wrong, you never do anything with the surename.
You'll need to do this:
char *Jones(char*, char* , char *);
int main() {
char name[]="Andrew";
char surname[]="Jones";
char result[80];
char *p;
p = Jones(name, surname, result);
puts(p);
return 0;
}
char *Jones(char *name, char *surname, char *result)
{
int length;
int i,k;
length = strlen(surname);
for (i=0; i<length ; i++)
{
result[i] = surname[i];
}
result[i++] = ' '; //add a space
length = strlen(name);
for (k=0; k<length ; k++, i++)
{
result[i] = name[k];
}
result[i] = 0; //add nul terminator to end the string
return result;
}
The conatenation could be simplified in many ways, e.g. to
strcpy(result, surename);
strcat(result, " ");
strcat(result, name);
or the Jones function could just do:
sprintf(result, "%s %s", surename, name);
In all cases, the function is rather fragile, as it's easy to overflow the result buffer if you pass in something else that does not fit within the result buffer.
1) The name and surname are char array and not single char so you have to change the input parameters types of your function Jones() the input parameters types should be char name[] (char array) or char *name (pointer to array of char)
2) You can not return an array defined locally and statically in the function. and if you want to return a string from the function, the string should be constant or it should be a buffer allocated dynamically (with malloc, calloc, realloc) into the function And for both cases the function type should be char *Jonas() and not char Jonas()
Or you can pass the result array via input parametr. and in this case you can fill it into the function.
void Jones(char *name, char *surname, char *result)
and in the main:
char result[80];
Jones(names, surname, result);
3) The following for loop is missing some thing
for (int i=0; i<50; i++)
{
result[length+i] = name[i];
}
The result elements from element 0 to element length are containing garbage because the result array is not initiated. so when you printf the result array you will get garbages printed. You have to initiate elements between 0 to length in the result array
#include <stdio.h>
#include <string.h>
char* Jones(char*, char*);
int main() {
char name[]="Andrew";
char surname[]="Jones";
puts(Jones(name,surname));
return 0;
}
char* Jones(char *name, char *surname)
{
strcat(surname," ");
strcat(surname,name);
return surname;
}

Splitting string with delimiters in C - segmentation fault

I want to write a function that will split a string into a char array. I know that the result array will ALWAYS have only two elements - servername and serverport. I wrote this, but it gives me "Segmentation fault" after compilation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* splitString(char stringToSplit[])
{
int i = 0;
char serverinfo[2];
char *tmp;
tmp = strtok(stringToSplit, ":");
while (tmp != NULL)
{
serverinfo[i] = tmp;
tmp = strtok(NULL, ":");
i++;
}
return serverinfo;
}
int main(int argc, char **argv)
{
char st[] = "servername:1234";
char *tab = splitString(st);
printf("%s\n", tab[0]);
printf("%s\n", tab[1]);
return 0;
}
char serverinfo[2];
allocates space for two chars, but you store char*s there, so make it
char* serverinfo[2];
But you return it from the function, however, the local variable doesn't exist anymore after the function returned, so you need to malloc it
char **serverinfo = malloc(2*sizeof *serverinfo);
and declare the function as
char **splitString(char stringToSplit[])
for the correct type.

String swap by swap function

I have written code to swap strings, but I am not able to swap. What is the problem and how can I solve it by using a function, swap?
#include <stdio.h>
void swap( char*,char*);
int main()
{
char *ptr[2] = {"hello", "morning"};
swap(ptr[0], ptr[1]);
printf("%s %s", ptr[0], ptr[1]);
return 0;
}
void swap(char *t1, char*t2)
{
char *t;
t = t1;
t1 = t2;
t2 = t;
}
I also tried to pass (&ptr[0], &ptr[1]), but here it shows a segmentation fault. Also I made a char, *p1 = ptr[0], char *p1 = ptr[1], and then passes &p1, and &p2 to swap, but still I get a segmentation fault.
C function arguments are pass-by-value. You're passing the value of addresses to your swap function, and expecting those values, the addresses, to change. But only the copies of the addresses in your swap function change.
To change the actual passed-in addressed, you'll need an aditional level of reference:
void swap(char **t1, char **t2)
{
char *t;
t = *t1;
*t1= *t2;
*t2 = t;
}
And call this swap like so: swap(&ptr[0], &ptr[1]);
You need to pass in pointers to the pointers of the char arrays in order to switch them. By doing that you can swap the values of those pointers instead. (Which are the actual arrays.)
#include<stdio.h>
void swap( char**,char**);
int main()
{
char *ptr[2] = {"hello","mornig"};
swap(&ptr[0], &ptr[1]);
printf("%s %s",ptr[0], ptr[1]);
return 0;
}
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
You need to pass pointers to your strings to swap them (char**). Otherwise the changes you do will be local to the swap function.
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
int main()
{
char *ptr[2] = {"hello","mornig"};
swap(&ptr[0], &ptr[1]);
printf("%s %s",ptr[0],ptr[1]);
return 0;
}
char *ptr[2] = {"hello","mornig"}; - This statement means you are allocating an array of size 2 which is going to store a address of two strings(ie char *). Now the two strings you are giving will be in text segment which is a read only data. If we tries to modify it, which will leads to crash(sgmentation fault).
So if you call swap(&ptr[0], &ptr[1]) leads to a crash. because you are trying to write the charcter m in the first read only string h. Write is not possible to the string which is in text segment.
If you want to simply swap a string you can call the function as swap(&ptr[0], &ptr[1]), which is equivalent to swap((ptr + 0),(ptr + 1));.
And change the swap function as below
void swap( char **t1,char **t2)
{
char *t;
t = *t1;
*t1 = *t2;
*t2 =t;
}
Here we are just swapping the address of the string stored in the array pointer ptr.

Problem with C char[] swapping

I have this short code:
#include <stdio.h>
void fastSwap (char **i, char **d)
{
char *t = *d;
*d = *i;
*i = t;
}
int main ()
{
char num1[] = "hello";
char num2[] = "class";
fastSwap ((char**)&num1,(char**)&num2);
printf ("%s\n",num1);
printf ("%s\n",num2);
return 0;
}
The output of this short program is:
claso
hells
and I just don't understand why the last letters of each char[] are swapped.
Any ideas?
fastSwap ((char**)&num1,(char**)&num2);
This is undefined behavior. You can't cast a pointer to array of char to a pointer to pointer to char. What you need is:
const char* num1 = "hello";
const char* num2 = "class";
fastSwap (&num1,&num2);
Also, you'll need to change the declaration of fastSwap and add inner-level const to arguments
void fastSwap (const char **i, const char **d)
I'm assuming you're trying to swap the contents of the num1 and num2 arrays by just manipulating pointers, so that after calling fastswap the contents of num1 will be "class" and num2 will be "hello".
If that's the case, then this won't work for a number of reasons. Arrays are not pointers, even though array expressions are often converted to pointer types. Secondly, you cannot modify the value of an array expression.
If you want to keep num1 and num2 as arrays (as opposed to pointers to string literals) and be able to swap their contents, you'll need to something more along these lines:
void fastswap(char *i, char *d)
{
while (*i && *d)
{
char t = *i;
*d++ = *i;
*i++ = t;
}
}
which will be called as
fastswap(num1, num2);
You are passing pointers to pointers to chars. You probably just want to pass pointers to chars like this:
#include <stdio.h>
void fastSwap (char *i, char *d)
{
char t = *d;
*d = *i;
*i = t;
}
int main ()
{
char num1[] = "hello";
char num2[] = "class";
fastSwap (num1,num2);
printf ("%s\n",num1);
printf ("%s\n",num2);
return 0;
}
This swaps the first character of the 2 char arrays.

Resources