Reputation: 2421
I'm working on a coding challenge where I have to read n bytes from an encoded file and perform some operations with them. I am trying to get the integer value of the bytes to use as a seed for srand()
.
I'm not sure I'm doing this properly. I am passing in 4 and file pointer to read_n_bytes()
in which I am reading 4 bytes from the file and writing them to a location in memory set aside with malloc()
. Then returning the malloc()
address as a char pointer as seed
and attempting to access the bytes with &seed
.
The rest of my operation isn't working here.
Am I going about this the right way?
char* seed;
int main() {
FILE * fp;
fp = fopen("flag.enc", "rb");
// extract seed from flag
seed = read_n_bytes(4, fp);
srand(&seed);
}
char* read_n_bytes(int b, FILE * fp) {
char * buffer;
buffer = malloc(b);
fread(buffer, 1, b, fp);
return buffer;
}
Upvotes: 0
Views: 278
Reputation: 8344
Below, I presume that the exercise involves a lot of integer values in the file, and the int
values returned from calls to rand()
. (Else, why worry about seeding with a constant value loaded from a file???)
Use main()
to "set up" and "tear down" the information you will work with. "Contain" the exercise to a separate function.
#include <stdio.h>
#include <stdlib.h>
// A function defined (before use) is a function declared!
exercise( int arr[], size_t nElem ) {
// whatever is the rest of the challenge
// arr[0] is first int (seed is not included )
// work with arr[0] to arr[ nElem - 1 ]
}
int main() {
char *fname = "flag.enc"; // prominent and re-usable
// attempt to open to read (binary mode)
FILE *fp = fopen( fname, "rb" );
if( fp == NULL ) {
fprintf( stderr, "Cannot open '%s'\n", fname ); // see?
exit( EXIT_FAILURE );
}
// measure the file (presuming reasonable size)
fseek( fp, 0, SEEK_END );
size_t fsize = ftell( fp );
fseek( fp, 0, SEEK_SET ); // rewind
/* Make BIG presumption that the data in the file is all integers */
/* 'seed' is unsigned, but 'rand()' will return signed integers */
size_t nInts = fsize / sizeof( int );
int *buf = malloc( nInts * sizeof *buf );
if( buf == NULL ) {
fprintf( stderr, "malloc failed. wanted %zu bytes\n", fsize );
fclose( fp );
exit( EXIT_FAILURE );
}
size_t nread = fread( buf, sizeof *buf, nInts, fp );
fclose(fp); // no longer needed
if( nread != nInts ) {
fprintf( stderr, "read %zu ints, not %zu (full file)\n", nread, nInts );
exit( EXIT_FAILURE );
}
srand( (unsigned int)buf[0] );
exercise( buf + 1, nInts - 1 ); // work with data that is loaded
free( buf );
return 0;
}
Upvotes: 1
Reputation: 595377
srand()
wants an integer, not a char**
pointer that you are trying to give it. You would have to typecast and dereference the pointer to access the integer value, eg:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
char* read_n_bytes(size_t b, FILE *fp);
int main() {
FILE *fp = fopen("flag.enc", "rb");
if (fp == NULL) {
// error handling...
}
// extract seed from flag
uint32_t *seed = (uint32_t*) read_n_bytes(sizeof(uint32_t), fp);
if (seed == NULL) {
// error handling...
}
srand(*seed);
free(seed);
fclose(fp);
}
char* read_n_bytes(size_t b, FILE *fp) {
char *buffer = malloc(b);
if (buffer) {
if (fread(buffer, b, 1, fp) != 1) {
free(buffer);
buffer = NULL;
}
}
return buffer;
}
Alternatively, get rid of malloc()
and let fread()
read directly into an integer variable, eg:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int read_n_bytes(void *buf, size_t b, FILE *fp);
int main() {
FILE *fp = fopen("flag.enc", "rb");
if (fp == NULL) {
// error handling...
}
// extract seed from flag
uint32_t seed;
if (read_n_bytes(&seed, sizeof(seed), fp) < 0) {
// error handling...
}
srand(seed);
fclose(fp);
}
int read_n_bytes(void *buf, size_t b, FILE *fp) {
return (fread(buf, b, 1, fp) != 1) ? -1 : 0;
}
Upvotes: 1