I have created a simple program that gets an existing file as input (text content) encrypts its content and the outputs the encrypted content to a file with filename specified by the user (argv[2]
). The problem is that whenever fgets
tries to read a new line character it terminates. So i would like to use fread
instead to solve this issue but then another problem came over. it doesn't stops at the ned of the string (\0
). So how can implement fread
to terminate at the end of the string? the source code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Xor_key 0xCF
void xorInput(char *in, char *o) {
FILE *fp;
FILE *fp2;
fp = fopen(in, "rb");
if (fp==NULL) {
printf("file isn't here...\n");
exit(1);
}
char buf[1000];
fgets(buf, sizeof(buf), fp);
printf("file contents: %s\n", buf);
int i;
for (i=0; buf[i] != '\0'; ++i) {
buf[i] ^= Xor_key;
}
printf("Encrypted input: %s\n", buf);
fclose(fp);
fp2 = fopen(o,"w");
fprintf(fp2, "%s", buf);
fclose(fp2);
}
int main(int argc, char *argv[]){
if (argc != 3) {
fprintf(stderr, "Usage: %s [file_name] [file_output_name]\n", argv[0]);
exit(1);
}
xorInput(argv[1], argv[2]);
return 0;
}
Adopting most of the suggestions from the comments, I created a file xr71.c
:
#include <stdio.h>
#include <stdlib.h>
#define Xor_key 0xCF
static
void xorInput(char *in_name, char *out_name)
{
FILE *fp1 = fopen(in_name, "rb");
if (fp1 == NULL)
{
fprintf(stderr, "failed to opn file %s for reading\n", in_name);
exit(1);
}
FILE *fp2 = fopen(out_name, "wb");
if (fp2 == NULL)
{
fprintf(stderr, "failed to open file %s for writing\n", out_name);
exit(1);
}
char buffer[1024];
size_t nbytes;
while ((nbytes = fread(buffer, 1, sizeof(buffer), fp1)) > 0)
{
for (size_t i = 0; i < nbytes; ++i)
buffer[i] ^= Xor_key;
if (fwrite(buffer, 1, nbytes, fp2) != nbytes)
{
fprintf(stderr, "failed to write %zu bytes to %s\n", nbytes, out_name);
exit(1);
}
}
fclose(fp1); // Error check omitted
fclose(fp2); // Error check omitted
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s file_name file_output_name\n", argv[0]);
exit(1);
}
xorInput(argv[1], argv[2]);
return 0;
}
Note that all error messages are written to standard error. The static
is there because of the compilation options I use (see below). Public functions must be declared before being defined; all functions must be declared or defined before being used — with the sole exception of main()
.
Compilation and test:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition xr71.c -o xr71
$ ./xr71 xr71 xr71.v1
$ ./xr71 xr71.v1 xr71.v2
$ cmp xr71 xr71.v2
$ cmp xr71.v1 xr71.v2
xr71.v1 xr71.v2 differ: char 1, line 1
$ cmp -l xr71.v1 xr71.v2
1 0 317
2 65 372
3 42 355
…
9034 252 145
9035 275 162
9036 317 0
$ ./xr71
Usage: xr71 file_name file_output_name
$ ./xr71 in
Usage: ./xr71 file_name file_output_name
$ ./xr71 in out err
Usage: ./xr71 file_name file_output_name
$
This is what should be expected. The output file xr71.v1
is different from the input file (that's good; it wouldn't be encrypted otherwise). The output file xr71.v2
is the same as the original input file (xr71
), which is good; encryption plus decryption gives you back what you started with.