stockoverflow
stockoverflow

Reputation: 1457

having problems with write() function in C

Given parts of my code:

char bmpheader[54] = {0x42, 0x4D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

char bmpimagedata[36] = {0x07, 0x07, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x66, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFF, 0xFF, 0xFF, 0x46, 0x00, 0x00};


while (i < 54) {
    printf("%c", bmpheader[i]);
    write (socket, bmpheader[i], 1);
    i++;
}
while (j < 36) {
    printf("%c", bmpimagedata[j]);
    write (socket, bmpimagedata[j], 1);
    j++;
}

I'm getting an error on my compiler saying passing argument 2 of 'write' makes pointer from integer without a cast for both write functions. I'm not too sure about the function's arguments itself (is the third argument correct?).

How can I correct it?

Upvotes: 0

Views: 280

Answers (7)

unwind
unwind

Reputation: 399703

Amazingly many weird/convoluted suggestions.

The canonical way to write out these two arrays is:

write(socket, bmpheader, sizeof bmpheader);
write(socket, bmpimagedata, sizeof bmpimagedata);

There's absolutely no point in doing computations to figure out the number of elements, involving the size of a single character, or anything. Just write the entire array, once for each, and be done.

Plus, of course, track if you succeeded or not (maybe only a part was written), and handle that.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1073968

The standard write function accepts a pointer to what you want to write out; you're passing it a char (which is being promoted to an int).

The minimal fix would be to change this:

write (socket, bmpheader[i], 1);

to

write (socket, &bmpheader[i], 1);

...but there are better ways.

You can just let write write out all 54 bytes itself:

write (socket, bmpheader, 54);

Or if you really want to do it a char at a time, you could use a pointer:

int i;
char *p;
for (i = 0, p = bmpheader; i < 54; ++i, ++p) {
    printf("%c", *p);
    write (socket, p, 1);
}

In either case, you want to avoid that magic number 54 and take it from the data. Since sizeof(char) is always one byte in standard C, you can use sizeof without doing the ugly sizeof(array) / sizeof(array[0]) thing:

int i;
char *p;
for (i = 0, p = bmpheader; i < sizeof(bmpheader); ++i, ++p) {
    printf("%c", *p);
    write (socket, p, 1);
}

...but I'm sure there's a more elegant solution than that.

You can also use putchar (fairly lightweight) instead of printf (fairly heavyweight):

int i;
char* p;
for (i = 0, p = bmpheader; i < sizeof(bmpheader); ++i, ++p) {
    putchar(*p);
    write (socket, p, 1);
}

And I used to do things like this with pointer arithmetic, no idea whether they're bad practice in the modern world:

char* p;
char* endp;
for (p = bmpheader, p = bmpheader + sizeof(bmpheader); p < endp; ++p) {
    putchar(*p);
    write (socket, p, 1);
}

Upvotes: 3

dubnde
dubnde

Reputation: 4431

signature for write is

ssize_t write(int fd, const void *buf, size_t count);

So second parameter should be a pointer and you are passing an actual value not a pointer. The following should help

write (socket, bmpheader + i, 1);
write (socket, bmpimagedata + j, 1);

But why not do

write (socket, bmpheader, sizeof(bmpheader)/sizeof(*bmpheader));
write (socket, bmpimagedata, sizeof(bmpimagedata)/sizeof(*bmpimagedata));

and checking the return value of course

Upvotes: 1

DXM
DXM

Reputation: 4543

If you change your code to...

write (socket, bmpimagedata + j, 1);

... it'll work. but you don't have to send your data one byte at a time, that's why third parameter is length.

Also have you considered looking up reference documentation for write() function to see exactly how it works and what it accepts? Learning to read and interpret documentation may not be easy, but in the long term would be much more beneficial than asking questions, "I'm not sure what third parameter is"

Upvotes: 0

Friedrich
Friedrich

Reputation: 5996

bmpimagedata[j]

is an integer you want to use &bmpimagedata[j]

Upvotes: 0

Saad Talaat
Saad Talaat

Reputation: 117

write (socket, &bmpimagedata[j], sizeof(bmpimagedata[j])); the second argument should be pointer and the third is the data size to be written

Upvotes: 0

Bruce
Bruce

Reputation: 7132

if you check prototype of write function, you'll see that second parameter is a char*. In your case, you're giving it a cell or your array, then a char. You should write:

write (socket, &(bmpheader[i]), 1);

Of course, this is far from being the most efficient, you could write directly

write (socket, bmpheader, 54);

Upvotes: 0

Related Questions