Now using malloc we have some dynamic stuff happening!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
take the infile | |
read the header | |
update the outfile header | |
to be double the infile header | |
allocate enough memory to store | |
double the data (MMaaxx) | |
write it to the outfile | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> //atoi() | |
int main(int argc, char* argv[]) | |
{ | |
/* | |
MAIN GOAL: | |
INPUT FILE HAS THE TEXT 3Max | |
OUTPUT FILE WILL HAVE 6MMaaxx | |
NOTE WE UPDATE OUR "HEADER" | |
note: you can change the | |
factor variable up to 3 and | |
everything should work the same | |
try it out! | |
*/ | |
int factor = 2; | |
if(argc != 3) | |
return 1; | |
/* | |
no error checking let's just get down to it | |
command line usage: ./filename <infile> <outfile> | |
in this case the factor will be hard coded in | |
to make it a little less complicated | |
infile will be a data.txt file with the text 3Max | |
When we open the outfile we are actually creating it... | |
unfortunately we have to use fopen() so don't let | |
that confuse you. Better if it was fcreate()!!!! | |
*/ | |
// infile stream | |
FILE* inptr = fopen(argv[1], "r"); | |
// outfile stream | |
FILE* outptr = fopen(argv[2], "w"); | |
// create a variable to hold our header data | |
// has to be an array type in this case | |
char inWidthChar[1]; | |
/* | |
read in the first char from our infile stream | |
remember this moves the FILE pointer forward by 1 char | |
so we're on the M after reading in the 3 within data.txt | |
it just happens on it's own. Just go with it! | |
*/ | |
fread(&inWidthChar, sizeof(char), 1, inptr); | |
/* | |
now width has the original width which is 3 | |
so let's create a different variable for the | |
outfile header to keep it tidy | |
*/ | |
int inWidth = atoi(inWidthChar); | |
int outWidth = inWidth * factor; | |
// yeah...this is a trick for converting int back to char | |
// https://bit.ly/2zWrZtF | |
char outWidthChar = outWidth + '0'; | |
// write it to the outfile | |
fwrite(&outWidthChar, sizeof(char), 1, outptr); | |
/* | |
Using malloc we can store chunks of size char | |
multiplied by whatever the outWidth is. We do | |
not need to know before hand. It can be any digit | |
between 0 and 9 and this will work. Make sure | |
the number of letters in the name match the | |
"header." Examples: 9Yzaguirre or 4John | |
*/ | |
char* name = malloc(sizeof(char)*outWidth); | |
/* | |
this is what we have in a drawing: | |
[c0][c1][c2][c3][c4][c5] | |
because they are each char data types | |
if we were to take the variable called | |
name and do something like: | |
*(name + 3) = 'z' | |
the drawing would look like this: | |
[c0][c1][c2][z][c4][c5] | |
we use that * right before name to say | |
"hey the VALUE not the address" | |
we are saying go to that memory location | |
and store the value 'z' (dereferencing the pointer) | |
It really be like that though! | |
watch how we use this in the loop | |
to build the first half of our dynamic name | |
data store | |
*/ | |
// temp char to hold each letter in the loop | |
char letter; | |
// keep note of this being out of the loop | |
int pointer_tracker = 0; | |
// loop through each letter of Max within the infile | |
for(int i = 0; i < inWidth; i++) | |
{ | |
fread(&letter, sizeof(char), 1, inptr); | |
// now we need to use that letter variable | |
// twice. Time for another inner loop! | |
for(int j = 0; j < factor; j++) | |
{ | |
*(name + pointer_tracker) = letter; | |
pointer_tracker++; | |
/* | |
remember the drawing | |
c0 c1 c2 c3 c4 c5 c6 | |
we need this to keep going up | |
so we can't use the inner counter | |
variables i or j because they reset | |
too often. | |
First loop we take in the M | |
then the inner loop takes M and assigns it | |
to c0 and c1 | |
then letter becomes a | |
the inner loop assigns c2 and c3 with a | |
once all the letters our complete our | |
name variable we used malloc() with has | |
the data MMaaxx so we just have to fwrite | |
to the outfile and we're home free! | |
We'll do this outside of both loops! | |
*/ | |
} | |
} | |
/* | |
so name is already a pointer type so we don't use | |
the & symbol. It's already an address to a value somewhere. | |
We need to write the correct number of bytes so keep that | |
in mind | |
*/ | |
fwrite(name, sizeof(char)*outWidth, 1, outptr); | |
// With dynamic memory we have to manually "free" it so it's | |
// available to the system again after runtime. Wow such confuse. | |
free(name); | |
// close the file streams and take a well deserved break! | |
fclose(inptr); | |
fclose(outptr); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment