Skip to content

Instantly share code, notes, and snippets.

@sojohnnysaid
Last active January 19, 2021 22:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sojohnnysaid/d3088453555bc6350d9e4fe8437d5297 to your computer and use it in GitHub Desktop.
Save sojohnnysaid/d3088453555bc6350d9e4fe8437d5297 to your computer and use it in GitHub Desktop.
Now using malloc we have some dynamic stuff happening!
/*
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