Can't read null terminated string from binary file in C - c

I have a which is launched in repl.it. The problem is that is doesn't properly reads null-terminated string from the file:
x == 228
y == Hell
x == 228
y == #
The last line should be y == Hell. How to fix my code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct A {
int x;
char *y;
};
#define INITIAL_BUFFER_LENGTH 10
char *read_string_from_file(FILE *handle) {
int string_capacity = 10;
char *string = malloc(string_capacity);
int count = 0;
char c;
while ((c = fgetc(handle)) != '\0') {
string[count] = c;
count++;
if (count == string_capacity) {
string_capacity *= 2;
string = realloc(string, string_capacity);
}
}
string[count] = '\0';
return string;
}
int main(void) {
struct A *obj = (struct A *)malloc(sizeof(struct A));
obj->x = 228;
obj->y = "Hell";
printf("x == %i\n", obj->x);
printf("y == %s\n", obj->y);
FILE *file = fopen("f.txt", "w");
fwrite(&obj->x, sizeof(obj->x), 1, file);
fwrite(&obj->y, strlen(obj->y) + 1, 1, file);
fclose(file);
obj->x = 0;
obj->y = NULL;
file = fopen("f.txt", "r");
fread(&obj->x, sizeof(obj->x), 1, file);
obj->y = read_string_from_file(file);
printf("x == %i\n", obj->x); // must be 228
printf("y == %s\n", obj->y); // must be Hell
return 0;
}

The relevant line is this one:
fwrite(&obj->y, strlen(obj->y) + 1, 1, file);
With this, you write the address of a pointer to the file.
What you want instead, is to write where the pointer points to:
fwrite(obj->y, strlen(obj->y) + 1, 1, file);

Related

How to loop a nested array in C

I've been developing a guessing game in which the goal is to guess the character selected by the user among specific characters, anyway, my first and only idea is to create an array with the questions to be asked, and each question has its options like in the code below I'm a newbie in C language so that I there are several things which I'm not sure how to handle. In short, I'd like to know how can I loop over the array showing to the user the questions with its questions to be answered? Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 500
#define LINE 200
//Read file and append to an array buffer
char *characters(){
char *source = NULL;
FILE *fp = fopen("file.txt", "r");
if (fp != NULL) {
/* Go to the end of the file. */
if (fseek(fp, 0L, SEEK_END) == 0) {
/* Get the size of the file. */
long bufsize = ftell(fp);
if (bufsize == -1) { /* Error */ }
/* Allocate our buffer to that size. */
source = malloc(sizeof(char) * (bufsize + 1));
/* Go back to the start of the file. */
if (fseek(fp, 0L, SEEK_SET) != 0) { /* Error */ }
/* Read the entire file into memory. */
size_t newLen = fread(source, sizeof(char), bufsize, fp);
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
} else {
source[newLen++] = '\0'; /* Just to be safe. */
}
}
fclose(fp);
}
return source;
}
char *strndup(const char *s, size_t n) {
char *p;
size_t n1;
for (n1 = 0; n1 < n && s[n1] != '\0'; n1++)
continue;
p = malloc(n + 1);
if (p != NULL) {
memcpy(p, s, n1);
p[n1] = '\0';
}
return p;
}
// User input
char *input(){
char *value;
char buffer[10];
int j = 0;
while( j < 1 && fgets(buffer, 10, stdin) != NULL){
value = strndup(buffer, 10);
j++;
}
return value;
}
// Main function
int main (void)
{
char *questions[] = {
"Genre",{"male","female"},
"Hair", {"black","red","blond"},
"Cloths",{"dress","shirt","pants"},
"pet", {"dog","cat","pig"}
};
int asked[4] = {0};
char *answers[5];
char buffer[6];
srand(time(NULL));
for (int i = 0; i < 4; i++) {
int q = rand() % 4;
while (asked[q])
q = rand() % 4;
asked[q]++;
printf ("%s\n", questions[q]);
answers[i] = input();
}
for(int i = 0; i < 4; i++)
{
printf(" %s ",answers[i]);
}
return 0;
}
That's the file's structure I'll compare as long as I have all the answers from the user.
female,blond,vestido,pig,character b
male,black,shirt,pants,dog,character c
male,black,shirt,pants,cat,character d
female,blond,dress,cat,character A
male,red,shirt,pants,pig,character e

How to find words with capital letters in a char using c?

I'm trying to find all the words with capital letters in a string, but am unable to process my data structure. i seem to be able to print out fileContent, indicating that it is loading in successfully, but my second function is not working on the file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* loadFile(char* fileName)
{
FILE *inputFile;
inputFile = fopen(fileName, "r");
//finds the end of the file
fseek(inputFile, 0, SEEK_END);
//stores the size of the file
int size = ftell(inputFile);
//Sets the scan to the start of the file
fseek(inputFile, 0, SEEK_SET);
char *documentStore = (char*)malloc(size);
int i = 0, c;
while((c = fgetc(inputFile)) != EOF)
{
documentStore[i] = c;
i++;
}
return documentStore;
}
void countImportantWords(char* fileContent, char** importantWords, int* frequencyWords)
{
int uniqueWordCount = 0;
int lengthWordStore = 10;
int i = 0;
int recording = 0;
char wordBuffer[50];
int wordBufferCount = 0;
int isWordPresent = 0;
while(fileContent[i] != EOF)
{
//To allocate more memory incase the structure is full
if(uniqueWordCount == lengthWordStore)
{
lengthWordStore += 10;
char** newWordStore = realloc(importantWords, lengthWordStore * sizeof(char*));
int* newFrequencyStore = realloc(frequencyWords, sizeof(int));
importantWords = newWordStore;
frequencyWords = newFrequencyStore;
}
printf("%s", wordBuffer);
//Conditions to fill if its a word
if(fileContent[i] >= 'A' && fileContent[i] <= 'Z' && recording == 0)
{
wordBuffer[0] = fileContent[i];
recording = 1;
}else if(fileContent[i] >= 'a' && fileContent[i] <= 'z' && recording == 1)
{
//each if is to check if the end of word is reached. Any character that is non alphabetical is considered end of word
wordBufferCount += 1;
wordBuffer[wordBufferCount] = fileContent[i];
} else if (fileContent[i] >= 'A' && fileContent[i] <= 'Z' && recording == 1)
{
wordBufferCount += 1;
wordBuffer[wordBufferCount] = fileContent[i];
} else {
//Adding a terminating character so that it strcpy only copies until that point
wordBuffer[wordBufferCount + 1] = '\0';
recording = 0;
//check to see if that word is in the array already, and if it is, it will just increment the frequency
for(int j = 0; j < uniqueWordCount; j++){
if(strcmp(wordBuffer, importantWords[j]) == 0)
{
frequencyWords[j] += 1;
isWordPresent = 1;
}
}
//if its not present, it should assign it to the structure
if(isWordPresent == 0)
{
char* wordStore = (char*)malloc(wordBufferCount * sizeof(char));
strcpy(wordStore, wordBuffer);
uniqueWordCount += 1;
importantWords[uniqueWordCount] = wordStore;
frequencyWords[uniqueWordCount] = 1;
}
}
i++;
}
}
int main() {
char fileName[50];
char *fileContent;
char **importantWords = (char**)malloc(10*sizeof(char**));
int *frequencyWords = (int*)malloc(10*sizeof(int));
printf("Please input the full file path: ");
scanf("%s", fileName);
fileContent = loadFile(fileName);
countImportantWords(fileContent, importantWords, frequencyWords);
int i = 0;
while(importantWords[i] != '\0')
{
printf("%s %d", importantWords[i], frequencyWords[i]);
i++;
}
return 0;
}
I've put in the full file so you can see how the structure was created incase that it is the issue, but ideally what would happen is that the final loop would print out all the words that are important and they're frequency. Currently i'm getting exit code 11, which i'm not sure what it means, but may be worth mentioning. I'd really appreciate any help :)
You can simplify the process dramatically but utilising functions and learning to manage your memory. I wrote a short example which does not take punctuation into account. It just assumes every word is separated by a space, which you can customise to your discretion.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char* readfile(char* filename){
char* data = NULL;
FILE* file = fopen(filename, "r");
if(file == NULL){
return NULL;
}
fseek(file, 0, SEEK_END);
long size = ftell(file)+1;
fseek(file, 0, SEEK_SET);
data = (char*)malloc(size);
if(data == NULL){
return NULL;
}
fgets(data, (int)size, file);
return data;
}
typedef struct uppercase_t{
char** word;
int count;
}uppercase;
void copy(uppercase* u,char* token){
size_t length = strlen(token);
u->word[u->count] = (char*)malloc(length+1);
if(u->word[u->count] == NULL){
return;
}
strcpy(u->word[u->count], token);
++u->count;
}
void createuppercasedata(uppercase* u, char* data){
const char delimeter[] = " ";
char* token = strtok(data, delimeter);
if(token == NULL){
return;
}
u->word = (char**)malloc(u->count+1);
if(u->word == NULL){
return;
}
if(isupper(token[0])){
copy(u,token);
}
while(token != NULL){
token = strtok(0, delimeter);
if(token != NULL)
if(isupper(token[0])) {
char** reallocated = (char**)realloc(u->word, u->count+1);
if(reallocated == NULL){
return;
}
u->word = reallocated;
copy(u, token);
}
}
}
void destroyuppercasedata(uppercase* u){
for(int index = 0; index < u->count; ++index){
free(u->word[index]);
}
free(u->word);
}
int main(){
char filename[] = "textfile";
char* data = readfile(filename);
if(data == NULL){
return -1;
}
uppercase u = {0};
createuppercasedata(&u, data);
printf("found %i uppercase words\n",u.count);
for(int index = 0; index < u.count; ++index){
printf("%s\n", u.word[index]);
}
destroyuppercasedata(&u);
free(data);
}
The code will allocate a new pointer for each uppercase and memory for the word to be copied too. It will free all the memory it allocated in the structure with destroyuppercasedata and it will free the initial data that was read from file. Error checking and memory management in C is really important. So utilise those properly.
This was the test file I used.
textfile
How many Uppercase words can Be Found In this text File the answer should be Seven
And this was the output to the terminal:
How
Uppercase
Be
Found
In
File
Seven

Binary read function doesn't work

I am new here and i need help for my homework. I have this binary file reader function which has been working very well until I changed a variable type in the a structure. So the variable was an int, and now it's a char[n] string in the geptipus structure.
And now the code freezes.
Here is the code :
typedef struct planetype
{
char t[10 + 1];
struct planetype next;
}planeytype;
typedef struct planedata
{
char name[60 + 1];
char nation[4 + 1];
int speed;
int max_altitude;
int takeoff_run;
int weight;
int max_bomb_weight;
int max_ammo_count;
double caliber;
struct planetype* tp;
struct planedata* next;
} planedata;
void new_type(planedata *akt, char* value) //pipa
{
planetype* type = (planetype*)malloc(sizeof(planetype));
strcpy(type->t, value);
type->next = akt->tp;
akt->tp = type;
//printf("%s", value);
}
void bin_read(planedata*head)
{
int IsEnd = 0;
char ch = '\0';
char tempname[40 + 1];
FILE *f1;
int n;
int i;
char *k;
planedata* data = head->next;
f1 = fopen("type.dat", "rb");
while (!IsEnd)
{
n = 0;
while (ch != ' ' && IsEnd != 1)
{
fread(&ch, sizeof(char), 1, f1);
if (ch == '\n')
{
IsEnd = 1;
}
if (ch != '\n')
{
tempname[n] = ch;
printf("%c", ch);
n++;
}
}
if (IsEnd != 1)
{
tempname[n - 1] = '\0';
printf("%s ", tempname);
data = PlaneName(head, tempname);
for (i = 0; i < 1; i++)
{
fread(&k, sizeof(int), 1, f1);
printf("%s", k);
new_type(data, k);
}
}
fread(&ch, sizeof(char), 1, f1);
}
fclose(f1);
}
The program dies when the debugger reaches the new_type function and the strcpy line.

reading a text file and sort it in a new file

I have a school assignment in which we have to read a text file, sort the words by alphabetical order and write the result into a new text file.
I've already got a program that can read the file and print it on the screen and a different program to sort words which you have to type in. Now I'm trying to merge these two programs, so that the data which been read out of the file will be put into the sorting program.
The program that we use to make the code is called CodeBlocks. Below are the two programs. I hope that you can give me advice and an example how to fix this because I tried everything I know but couldn't get it working.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#define MAX_NUMBER_WORDS 100
char* ReadFile(char *filename)
{
char *buffer = NULL;
int string_size, read_size;
FILE *handler = fopen(filename, "r");
if (handler)
{
//seek the last byte of the file
fseek(handler, 0, SEEK_END);
//offset from the first to the last byte, or in other words, filesize
string_size = ftell(handler);
//go back to the start of the file
rewind(handler);
//allocate a string that can hold it all
buffer = (char*)malloc(sizeof(char) * (string_size + 1));
//read it all in one operation
read_size = fread(buffer, sizeof(char), string_size, handler);
//fread doesnt set it so put a \0 in the last position
//and buffer is now officialy a string
buffer[string_size] = '\0';
if (string_size != read_size)
{
//something went wrong, throw away the memory and set
//the buffer to NULL
free(buffer);
buffer = NULL;
}
}
return buffer;
}
int numberOfWordsInDict(char **dict)
{
int i;
for (i = 0; i < MAX_NUMBER_WORDS; i++)
{
if (dict[i] == NULL)
return i;
}
return MAX_NUMBER_WORDS;
}
void printDict(char **dict)
{
int i;
printf("Dictionary:\n");
for (i = 0; i < numberOfWordsInDict(dict); i++)
printf("- %s\n", dict[i]);
if (numberOfWordsInDict(dict) == 0)
printf("The dictionary is empty.\n");
}
void swapWords(char **dict, char *word, char *word2)
{
int i, p1 = -1, p2 = -1;
char *tmp;
for (i = 0; i < numberOfWordsInDict(dict); i++)
{
if (strcmp(dict[i], word) == 0)
p1 = i;
if (strcmp(dict[i], word2) == 0)
p2 = i;
}
if (p1 != -1 && p2 != -1)
{
tmp = dict[p1];
dict[p1] = dict[p2];
dict[p2] = tmp;
}
}
void sortDict(char **dict)
{
int swap;
int i = 0;
do
{
swap = 0;
for (i = 0; i < numberOfWordsInDict(dict) - 1; i++)
{
if (strcmp(dict[i], dict[i + 1]) > 0)
{
swapWords(dict, dict[i], dict[i + 1]);
swap = 1;
}
}
} while (swap == 1);
}
void splitSentenceToWords(char **words, char *sentence)
{
int p1 = 0, p2 = 0;
int nrwords = 0;
char *word;
while (sentence[p2] != '\0')
{
if (isspace(sentence[p2]) && p1 != p2)
{
word = (char*)malloc(sizeof(char)*(p2 - p1 + 1));
words[nrwords] = word;
strncpy(words[nrwords], &sentence[p1], p2 - p1);
words[nrwords][p2 - p1] = '\0';
nrwords++;
p1 = p2 + 1;
p2 = p1;
}
else
{
p2++;
}
}
if (p1 != p2)
{
word = (char*)malloc(sizeof(char)*(p2 - p1 + 1));
words[nrwords] = word;
strncpy(words[nrwords], &sentence[p1], p2 - p1);
words[nrwords][p2 - p1] = '\0';
nrwords++;
p1 = p2 + 1;
p2 = p1;
}
}
int main(void)
{
char sentence[1024];
char *dict[MAX_NUMBER_WORDS] = {};
char *words[MAX_NUMBER_WORDS] = {};
char *string = ReadFile("test.txt");
if (string)
{
puts(string);
free(string);
}
//printf("Type een zin in: ");
scanf("%[^\n]s", &sentence);
splitSentenceToWords(words, &sentence);
printDict(words);
printf("Words has been sorted\n");
sortDict(words);
printDict(words);
return 0;
}
You are on the right track. The problem is that after your read in your file, you are not using the input to build your word list. Instead of;
splitSentenceToWords(words, &sentence);
try:
splitSentenceToWords(words, &string);
Delete
free(string)
This will get you started. You will have to clean this up when you understand it a bit better.

C corruption or double free, why?

I have a C code (first C code I have ever written), and there is an error in it, but I dont know, where. When I try to free a variable (dinamically allocated, its name is out_html) I get double free or corruption. I have no idea why my program does this, I checked all my calls for free etc.
The code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "fcntl.h"
#include "errno.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
#define MAX_SIZE 512
typedef struct node
{
char* data;
struct node * nextnode;
} node;
int max(int a, int b)
{
if(a>b) return a;
else return b;
}
node* push(node * stackTop, char* data)
{
//static
node* newItem;
newItem = calloc(sizeof(node),1);
newItem->data = data;
newItem->nextnode = stackTop;
return newItem;
}
node* pop(node* stackTop)
{
if(stackTop != NULL)
{
free(stackTop->data);
node* P = stackTop;
return stackTop->nextnode;
free(P);
}else return NULL;
}
int isMajorTag(char* tag)
{
if(strcmp(tag, "<html>") == 0 || strcmp(tag, "</html>") == 0 ||
strcmp(tag, "<body>") == 0 || strcmp(tag, "</body>") == 0 ||
strcmp(tag, "<head>") == 0 || strcmp(tag, "</head>") == 0 ) { return 1; }
else { return 0; };
}
int isHTMLtag(char* tag, char* tags)
{
char* tag2;
if(strstr(tag," ") != NULL)
{
char* strptr = strstr(tag, " ");
int End = strptr - tag;
char* tag_ = strndup(tag, End);
tag2 = calloc((strlen(tag_) + strlen("*") + 2), sizeof(char));
strcpy(tag2, tag_);
strcat(tag2,"*");
free(tag_);
}
else tag2 = tag;
int ret;
if(strstr(tags, tag2) != NULL){ ret = 1; }
else { ret = 0; };
if(tag2 != tag ) free(tag2);
return ret;
}
int isCloserTagOf(char* cltag, char* tag)
{
int ret = 1;
if( cltag[1] != '/' ) ret = 0;
if( tag[1] == '/' ) ret = 0;
char* ntag;
char* ncltag;
if(strstr(tag," ") != NULL)
{
char* strptr = strstr(tag, " ");
int End = strptr - tag;
ntag = strndup(tag, End) + 1;
// ntag = calloc(strlen(ntag0) + 1 + 1, sizeof(char)); strcpy(ntag, ntag0); strcat(ntag, ">");
ncltag = strndup(cltag+2,strlen(cltag) - 3);
} else
{
ntag = tag + 1;
ncltag = cltag + 2;
}
// printf("|%s|%s| %i", ntag, ncltag, strcmp(ncltag, ntag));
if(strcmp(ncltag, ntag) != 0) ret = 0;
return ret;
}
int isIndividualTag(char* tag)
{
if(strcmp(tag,"</br>") == 0) return 1;
else if(strncmp(tag,"<!--#include file=",18) == 0) return 2;
else if(strncmp(tag,"<!--#echo var=",14) == 0) return 3;
else if(strncmp(tag,"<!--",4) == 0) return 4;
else return 0;
}
int main(int argc,char *argv[])
{
char* fname;
if(argc == 2)
{
fname = argv[1];
} else
{
printf("Give me a filename!");
fname = calloc( MAX_SIZE, sizeof(char));
scanf("%s", fname);
};
printf("Parameter: %s \n\n", fname);
// beolvasas
int f = open(fname, O_RDONLY);
long pos = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);
char *buff = calloc(pos,1);
read(f, buff, pos);
close(f);
f = open("valid-tags", O_RDONLY);
pos = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);
char *valids = calloc(pos,1);
read(f, valids, pos);
close(f);
// printf("File: %s %s %i ",buff, valids, isCloserTagOf("</html>","<html>")); printf("Igen? %i", isHTMLtag("</head>",valids));
node* Stack = NULL;
char *P = buff;
int is_valid = 1;
int bodyCnt = 0;
char* body[6];
int correct_body = 1;
char* out_html = calloc(strlen(buff), sizeof(char));
while(P[0] != '\0' )
{
if(P[0] == '<')
{
char* strptr = strstr(P, ">");
if(strptr != NULL)
{
int nextCloser = strptr - P + 1;
char* tag = strndup(P, nextCloser);
int IsIndividual = isIndividualTag(tag);
if(isHTMLtag(tag, valids) || IsIndividual)
{
if(IsIndividual)
{
if(IsIndividual == 2) // file inclusion
{
char* firstQ = strstr(tag, "\"");
char* secondQ;
if( firstQ ) secondQ = strstr(firstQ + 1, "\"");
if( firstQ && secondQ )
{
char* incl_filename = strndup((firstQ + 1), (secondQ - firstQ - 1));
f = open(incl_filename, O_RDONLY);
pos = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);
char *inclstr = calloc(pos,1);
read(f, inclstr, pos);
close(f);
char* new_out_html = calloc((max(strlen(buff),strlen(out_html)) + pos + 1 + 1 + 1), sizeof(char));
strcpy(new_out_html, out_html);
strcat(new_out_html, inclstr);
free(out_html); out_html = NULL; // free(inclstr);
out_html = new_out_html;
} else
{
printf("Invalid file inclusion! \n");
is_valid = 0; break;
};
} else if (IsIndividual == 3) // date time
{
time_t t = time(NULL);
// int nDigits = floor(log10(abs(t)) + 1; (strlen(out_html) + nDigits
char* timestring = ctime(&t);
char* new_out_html = calloc(1 + max(strlen(buff),strlen(out_html)) + strlen(timestring), sizeof(char));
strcpy(new_out_html, out_html);
strcat(new_out_html, timestring);
//printf("%s",new_out_html);
free(out_html); out_html = NULL; // free(timestring);
out_html = new_out_html;
} else
{
strcat(out_html, tag);
};
}else
{
strcat(out_html, tag);
if(Stack != NULL && isCloserTagOf(tag,Stack->data))
{
Stack = pop(Stack);
}else
{
Stack = push(Stack, tag);
};
}
if(isMajorTag(tag))
{
if(bodyCnt < 6)
{ body[bodyCnt] = calloc(strlen(tag), sizeof(char));
strcpy(body[bodyCnt],tag);
++bodyCnt;
}else
{
printf("Too much major html tag found...");
correct_body = 0;
}
}
}else
{
printf("Invalid html tag: %s \n", tag);
is_valid = 0;
break;
}
P = P + nextCloser;
}
else
{
printf("Unclosed tag\n");
is_valid = 0;
break;
}
} else
{ //printf("-%c",P[0]);
strncat(out_html, P,1);
// printf("{(%s)}",out_html);
P = P + 1;
};
};
int i;
char* correctBody[] = { "<html>", "<head>", "</head>", "<body>", "</body>", "</html>"};
for(i = 0; i < bodyCnt && correct_body; ++i) {
correct_body = (strcmp(body[i],correctBody[i]) == 0); }
if(is_valid && Stack == NULL &&
correct_body && bodyCnt == 6){ printf("\nValid HTML Code\n");
printf("\n\n%s\n",out_html);
}
else printf("\nInvalid.\n");
// printf("%i %i %i",bodyCnt,correct_body,is_valid);
/*****************************************************************/
for(i=0;i<bodyCnt;++i) free(body[i]);
free(buff); free(valids); //
if(out_html != NULL) free(out_html);
return 0;
}
At the end of the code:
if(out_html != NULL) free(out_html);
Without this, there is no crash.
I think the crash is caused somewhere near line 196.
(there must be a valig-html file with proper html tags - without this, the code is useless, I mean a file like this: )
The error message can be a bit confusing.
When allocation say 200 bytes with calloc, the routine internally allocates a tad more:
say 8 , 16 or 32 bytes to make linked lists and other bookkeeping (i.e. has it been freed).
If the strings that are appended or copied with strcpy/strcat do not fit the target array, it internally leads to possible corruption of the bookkeeping.
So the error doesn't necessarily do anything with freeing a pointer twice.
It is hard to figure out what's going on in your code, but some potentically nonsensical operations are visible at the first sight. For example, consider this sequence
int f = open(fname, O_RDONLY);
long pos = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);
char *buff = calloc(pos,1);
read(f, buff, pos);
close(f);
...
char* out_html = calloc(strlen(buff), sizeof(char));
You read contents of some file into an allocated buffer buff (the size of the buffer is exactly the size of the file). And later you treat buff as a null-terminated string: you use it as an argument of strlen.
But you never bothered to null-teriminate your buff! How is this supposed to work? If it is not null-terminated, it is not a string and it cannot be meaningfully used as an argument of strlen.
You program contains several instances of code that follows the same pattern: the entire contents of some file is read into a buffer of the exact size and then interpreted as a null-terminated string, while in reality it is not null-terminated (nobody bothered to ensure null-termination).
Is the terminating zero supposed to be present in the file itself? If so, then how are we supposed to know that? We are not telepathes here.
This looks wrong:
(BTW: I could not find a definition / declaration of stackTop)
node* pop(node* stackTop)
{
if(stackTop != NULL)
{
free(stackTop->data);
node* P = stackTop;
return stackTop->nextnode;
free(P);
}else return NULL;
}
Here is another calloc() that's too short. (the strcpy() will put its nul byte at a place that does not belong to the calloc()ed object. BTW: sizeof(char) is 1, by definition.
if(bodyCnt < 6)
{ body[bodyCnt] = calloc(strlen(tag), sizeof(char));
strcpy(body[bodyCnt],tag);
++bodyCnt;
}else
{
printf("Too much major html tag found...");
correct_body = 0;
}

Resources