Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using read as a system call

Status
Not open for further replies.

afternoondelite

Programmer
Aug 31, 2007
5
0
0
US
I have to create a program with a system call and something is driving me nuts.

For some reason I get really odd results from a file with an odd number of characters:

48 struct stat buffer1;
49 fstat(d1, &buffer1);
50 size_t tot_bytes1 = buffer1.st_size;
51 char *buff1 = malloc(tot_bytes1);
52
53 printf("buff1 len: %d\n", sizeof(buff1));
54
55 ssize_t bytes_read= read(d1, buff1, tot_bytes1);
56
57 printf("tot_bytes: %d\n", (int)tot_bytes1);
58 printf("buff1 len: %d\n", strlen(buff1));
59 printf("bytes_read: %d\n", (int)bytes_read);
60 printf("%s\n", buff1);

buff1 len: 4
tot_bytes: 12
buff1 len: 15
bytes_read: 12
hello world
Ù

And those are the results for one.

And after adding a character to the file:

buff1 len: 4
tot_bytes: 13
buff1 len: 13
bytes_read: 13
hello worlds




 
Checking each character on the first one.
char:h
char:e
char:l
char:l
char:eek:
char:
char:w
char:eek:
char:r
char:l
char:d
char:

char:Ù
char:
char:


Checking each character on the second one:
buff1 len: 4
tot_bytes: 15
buff1 len: 15
bytes_read: 15
hello worldsss

char:h
char:e
char:l
char:l
char:eek:
char:
char:w
char:eek:
char:r
char:l
char:d
char:s
char:s
char:s
char:

 
Code:
char *buff1 = malloc(tot_bytes1);
You forgot to add 1 more byte for the NULL terminator...
It might be better if your print out the hex values of each byte so you can see what those blank characters are.
 
I tried doing + 1 after I realized that, but it didn't work either.

It was as if too much space was being allocated if the byte size was odd.

I ended up multiplying the total byte size by two and allocating that space and it worked out just fine. I'm sure that's not the appropriate way to handle it, though.


is the actual code

I dumped the values of each byte from the output file, and I got 021 in Ascii or an actual !


./main helloworld brownfox

that file is brownfox

Here's a better example:

after appending at the end of the file:


0000000 t h e b r o w n f o x j u
0000020 m p e d h i g h i n t h e
0000040 a i r \n h e l l o w o r l d
0000060 \n
0000061



after appending it randomly:


0000000 t h e b r o w n f o h e l l
0000020 o w o r l d \n ! x j u m p e
0000040 d h i g h i n t h e a i
0000060 r \n h e l l o w o r l d \n
0000076
 
read() doesn't add the \0 for you, in addition to the problem of not allocating space for the \0.

You need to add it yourself if [tt]printf("%s")[/tt] isn't going to print a bunch of trailing garbage.

Eg.
Code:
char *buff1 = malloc(tot_bytes1+1);
ssize_t bytes_read= read(d1, buff1, tot_bytes1);
buff1[bytes_read]='\0';


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Yeah, I tried that as well.

Worked fine for printf.

I commented it out.

It did not work for write when I wrote it out to the file. It would write the entire buffer to the file.
 
> 12 #define EQ ==
> 13 #define OR ||
Please don't do this.
Using the pre-processor to rewrite the language is not a good idea.

> char *output = malloc(strlen(file1) + 1 + strlen(file2) + 1);
This is 1 byte short as well. The two +1 account for the two "\n" you append, but there's still the matter of the "\0" which all strings need.

> I commented it out.
Well put it back in, and put in in a place where it will actually do some good, like immediately after you read the data.

This for example, is completely useless.
Code:
 55   ssize_t bytes_read= read(d1, buff1, tot_bytes1);
 56   
 57   printf("tot_bytes: %d\n", (int)tot_bytes1);
 58   printf("buff1 len: %d\n", [red]strlen[/red](buff1));
 59   printf("bytes_read: %d\n", (int)bytes_read);
 60 
 61   //buff1[tot_bytes1] = '\0';
Bzzt - too late, strlen() already goofed because it too relies of a \0 in the correct place.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
Thank you very much, Salem.
Worked like a charm.

And about the macros, hah.. I was actually suggested to do that from this one website I was trying to figure out this on. Thanks for that link.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top