add bytes to file

K

Keith Thompson

Greg Martin said:
There's lots of ways to accomplish this. This would work. Whether it's
what you need is another matter.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
FILE* out;
char bytes[] = { '\0', '\0', '\0' };
int sz = sizeof (bytes) / sizeof (bytes[0]);
int nw;

if (argc < 2) {
return EXIT_FAILURE;
}

if ((out = fopen (argv[1], "a")) != NULL) {
nw = fwrite (bytes, sizeof (bytes[0]), sz, out);
if (nw != sz) {
perror ("fwrite");
}

fclose (out);
}

return 0;
}

fopen()'s mode "a" is *text* append mode:

append; open or create text file for writing at end-of-file

If you write characters other than printable characters, '\n', and
'\t' to a text stream, they won't necessarily appear when you read
them back; see N1370 7.21.2p2 for details.

If you're writing 0 bytes to a file, you (obviously, I think)
need to do it in binary mode, probably by passing "ab" as the mode
argument to fopen().

Even that's not guaranteed to work since a binary stream "may,
however, have an implementation-defined number of null characters
appended to the end of the stream" (N1370 7.21.2p3). This would
most likely apply to a system that tracks sizes of binary files
in blocks rather than bytes. It almost certainly wouldn't be a
concern for any system the OP is likely to be using.
 
G

Greg Martin

Greg Martin said:
There's lots of ways to accomplish this. This would work. Whether it's
what you need is another matter.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
FILE* out;
char bytes[] = { '\0', '\0', '\0' };
int sz = sizeof (bytes) / sizeof (bytes[0]);
int nw;

if (argc < 2) {
return EXIT_FAILURE;
}

if ((out = fopen (argv[1], "a")) != NULL) {
nw = fwrite (bytes, sizeof (bytes[0]), sz, out);
if (nw != sz) {
perror ("fwrite");
}

fclose (out);
}

return 0;
}

fopen()'s mode "a" is *text* append mode:

append; open or create text file for writing at end-of-file

If you write characters other than printable characters, '\n', and
'\t' to a text stream, they won't necessarily appear when you read
them back; see N1370 7.21.2p2 for details.

If you're writing 0 bytes to a file, you (obviously, I think)
need to do it in binary mode, probably by passing "ab" as the mode
argument to fopen().

Even that's not guaranteed to work since a binary stream "may,
however, have an implementation-defined number of null characters
appended to the end of the stream" (N1370 7.21.2p3). This would
most likely apply to a system that tracks sizes of binary files
in blocks rather than bytes. It almost certainly wouldn't be a
concern for any system the OP is likely to be using.

Good point though the NUL character doesn't have meaning in binary -
it's just plain old 0x00. However, on the OP's system it works the same
either way since his OS doesn't distinguish between formats.

e.g.
file three_nulls data
wc three_nulls
0 0 3
 
M

Mich Ravera

Bill Cunningham said:
Can someone show me how to add 3 or so bytes to the end of a file? I
have been studying and I'm thinking fseek() and fgetc() might be involved.
I can't seem to find any examples online unless I'm overlooking something.
Nothing in C that is.

I read some of your later posts in the thread. When doing encryption, the
standard method is not to pad the file itself, but to pad the data
internally. This is usually with the first part of the string
"\0\1\2\3\4\5\6\7" that is required to make the multiple of eight bytes.

If you pad the file itself, an additional 8 bytes will be added. And so on,
and so on....

The basic algorithm is to:
1) get a buffer that is at least 8 bytes too long for the file
2) Read the whole file into the buffer
3) append the padding string
4) find the length that is a multiple of eight
((bytes_in_file+8)&0xfffffff8) [or 0xfffffffffffffff8 or 0xfff8]
5) encrypt that many bytes
6) write out the encrypted buffer


When you decrypt, you will throw away the last bytes that look like padding.
 
D

David Thompson

I read some of your later posts in the thread. When doing encryption, the
standard method is not to pad the file itself, but to pad the data

Yes. But:
internally. This is usually with the first part of the string
"\0\1\2\3\4\5\6\7" that is required to make the multiple of eight bytes.
Usually? Although that is a possible general-purpose padding, I've
never seen it. The most common general padding by far IME is "PKCS#5"
padding (adopted by quite a few other standards since) which is
\1 if one byte is needed
\2\2 if two bytes are needed
.... up to blocksize (always at least one byte)
(I say general-purpose because there are also application-specific
paddings in some standards, especially X9.* banking.)
If you pad the file itself, an additional 8 bytes will be added. And so on,
and so on....
To be exact, the required alignment for block modes like CBC and CTR
(and ECB but using ECB is almost always a bad idea) is the blocksize
of the block primitive. For DES and "triple-DES" (*), and Blowfish and
CAST, it is 8 bytes. For AES/Rijndael and the other candidates like
Twofish, and some other newer ciphers, it is 16. It can be more.

(*) <peeve> There is not and never was anything named triple-DES.
There was a standard DES specifying DEA, then a standard DES
specifying DEA and TripleDEA, and now no standard at all only an SP.
But everyone still calls them DES and TripleDES or 3DES. said:
The basic algorithm is to:
1) get a buffer that is at least 8 bytes too long for the file
2) Read the whole file into the buffer
3) append the padding string
4) find the length that is a multiple of eight
((bytes_in_file+8)&0xfffffff8) [or 0xfffffffffffffff8 or 0xfff8]

ObTopic: use ~ 7 of the appropriate type ~7U ~7UL ~7ULL or ~(cast)7,
or -8U -8UL -8ULL -(cast)8, so you don't have to get the width right
manually. Or IMHO better instead use %8U -- that's what you actually
mean so it's clearer to human readers, and any compiler that doesn't
convert _unsigned_ %powerof2 to &lowbits is too stupid to use at all.
(_signed_ %powerof2 is not the same as &lowbits for negative values;
this is one of many reasons not to do bit operations on signed.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top