keivn
keivn

Reputation: 114

C fwrite function giving data with unknow space

This function is supposed to get a parameter as the pointer of a file and put all file into the struct anagram, then write it to another file. Right now the each data has a lot of space bewteen them. The charCompare is working fine since i make a test file to test it.

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "anagrams.h"
#define SIZE 80

//struct
struct anagram {
char word[SIZE];
char sorted[SIZE];
};

void buildDB ( const char *const dbFilename ){

    FILE *dict, *anagramsFile;
    struct anagram a;

    //check if dict and anagram.data are open
    errno=0;
    dict= fopen(dbFilename, "r");

    if(errno!=0) {
        perror(dbFilename);
        exit(1);
    }

    errno=0;

    anagramsFile = fopen(anagramDB,"wb");

    char word[SIZE];
    char *pos;
    int i=0;

    while(fgets(word, SIZE, dict) !=NULL){

        //get ripe of the '\n'
        pos=strchr(word, '\n');
        *pos = '\0';

        //lowercase word
        int j=0;
        while (word[j]){
            tolower(word[j]);
            j++;
        }

        /* sort array using qsort functions */ 
        qsort(word,strlen(word), sizeof(char), charCompare);

        strncpy(a.sorted,word,sizeof(word));

        fwrite(&a,1,sizeof(struct word),anagramsFile);

        i++;
    }
    fclose(dict);
    fclose(anagramsFile);

}

data: 10th 1st 2nd

Upvotes: 2

Views: 303

Answers (1)

hmjd
hmjd

Reputation: 121961

A probable cause is the size argument passed to qsort(). From the linked reference page for qsort():

size - size of each element in the array in bytes

Therefore the size argument should be 1, which is guaranteed to be sizeof(char), and not sizeof(char*) which is likely to be 4 or 8. The posted code incorrectly informs qsort() that word is pointing to an array of 4 (or 8) times larger than the actual array and qsort() will access memory it is not supposed to. Change to:

qsort(word,strlen(word), 1, charCompare);

Another possible cause is buffer overrun caused by this line:

strncpy(&a.sorted[i],word,sizeof(word));

i is being incremented on every iteration of the while loop but sizeof(word) is always being written. The values of SIZE and BUFSIZ are not posted but even if they were equal the strncpy() will write beyond the bounds of a.sorted after the first iteration.

Other points:

  • fgets() is not guaranteed to read the new-line character so check return value of strchr() before dereferencing it.
  • tolower() returns the lowercase character, it does not change its argument.
  • why read into a temporary buffer (word) and copy? Just read directly into the struct members.

Upvotes: 3

Related Questions