tags:

views:

115

answers:

3

Hi

Could someone please tell us to print a char when receiving data as a struct? Here is an example:

...
struct rcv{
  int x1;
  float x2;
  char *x3;
}; 
rcv data_rcv;
...
if (recv(socket, &data_rcv, sizeof(data_rcv), 0) < 0)
printf("recv() failed");
...

printf("x1 = %d\n", data_rcv.x1);
printf("x2 = %f\n", data_rcv.x2); 

printf("x3 = %s\n", data_rcv.x3); // it doesn't print anything, why? 
...

Let's suppose that x3 is string transfered through a socket, as such:

...
char *str1="data-of-app.1"

struct snd{
  int x1;
  float x2;
  char *x3;
}; 
snd data_snd;
...
data_snd.snd = str1;
...
if (send(socket, &data_snd, sizeof(data_snd), 0) < 0)
printf("send() failed");
...

Thanks for your replies-

+5  A: 
printf("x3 = %s\n", data_rcv.x3);

should be

printf("x3 = %c\n", data_rcv.x3);
Mincho
@mincho thanks for the reply ..
make
The answer posted by caf is better.
ArunSaha
+4  A: 

%s tries to print a null-terminated string, and expects the parameter to be a char pointer. Instead it is getting a char value (and since a pointer on all modern machines is larger than a char, it's also getting some garbage after it), which is very bad.

Instead, you should use %c.

Max Shawabkeh
thanks for reply. even when using %c, it doesn't print the whole string ... it displays only one character... so is there any othe way? thanks!
make
If you're sending a string rather than a single character as your edit suggests, follow caf's answer.
Max Shawabkeh
@max-shawabkeh .. thanks! yes , you are right ... sorry i forgot to put * when I posted a question ... thanks again for the reply!
make
+5  A: 

In your example, x3 is not a char - it's a pointer to char. In most cases, pointer values are only meaningful in the process that they originally belonged to. If you send a pointer value to another process through a socket, the receiving process can't usually make any use of it.

What you probably want to do instead is to send an array of char (or possibly just a single char, it's hard to tell from your question) - so your struct should look like:

struct rcv {
  int x1;
  float x2;
  char x3[LENGTH];
}; 

or maybe:

struct rcv {
  int x1;
  float x2;
  char x3;
}; 

(If you use the second form, you will need to use %c instead of %s in the printf format string).

As an additional thought, you should bear in mind that if you are sending to a process that isn't compiled with the same compiler and targetting the same architecture, the size and layout of the struct itself, as well as that of the individual members, is unlikely to match up and you will recieve garbage.


In answer to your question in comments:

You should use the same struct definition on both the sending and recieving sides. If you have a struct like this:

#define N 100

struct rcv {
    int x1;
    float x2;
    char x3[N];
};

...and you want to put a string into the x3 member, just use strcpy (or better, strncat):

struct rcv data;

data.x3[0] = 0;
strncat(data.x3, some_string, N - 1);
caf
thanks for your reply. the problem is not about the compiler, as i am using the same and the same compiler ...but it is how to send char through sockets when dealing with struct() ... thanks again
make
Sure, that was just extra information that I was throwing there at the end. The main point is that your `struct` doesn't contain a `char` at all - it contains a `char *`, which is (usually) meaningless to send between processes. To fix your problem, you need to change that `char *` member to either `char [N]` or a `char`.
caf
@make - you are dismissing very good advice here.
Hans Passant
@nobugz thanks! for your advise ...
make
@Caf ... thanks! a lot for your suggestions. you are right! we can 't send a pointer through a socket . Just another question plz ... how can we assign char of struct to another as such e.g., #define N=100 ... struct snd {char x3[N];}; snd data_snd; ... struct rcv {char x3[N];};rcv data_rcv; ... data_rcv.x3=data_snd.x3; //this is not working ... i tried even strcpy(), it doesn't compile ... thanks for your help!
make
Instead of `struct snd` and `struct rcv`, you should use the same structure definition on both sides. See the update to my answer.
caf
+1: Good answer.
ArunSaha