0

So im brand new to C. I need to write a program that takes in a binary file of integers as input, allocate a big enough array with malloc, then use the read() c function to store each integer in the binary file in its respective location in the array. My issue is that I don't know how to differentiate between the two. when I print out the data stored in this allocated array space it just shows the Ascii value of the binary data taken as a string of chars. so for example if I have the binary number 0000 0001, the array from locations [0]-[7] would be each ascii value of each bit in that binary number.

Basically im trying to read each line and store that lines int representation of the binary information in 1 array location, so like the above example the desired outcome would be: [0] - 1. Is there some conversion algorithm I need to do? I believe there to be a way for c to just recognize that its binary info, not ascii because there are 2 different file types: binary and ASCII. Any help would be greatly appreciated, thanks in advance!

P.s I can only use these function calls: open, close, read, malloc, fstat, printf

else
    {
            fileDescriptor = open(argv[1], O_RDONLY, 0);
            if (fileDescriptor == -1){
                    printf("File Not Found\n");
                    exit(1);
            }
            else{
                    if (fstat(fileDescriptor, &fileStat) < 0){
                            printf("Trouble pulling statistics of file\n");
                            exit(1);
                    }
                    else
                    {
                            numBytes = fileStat.st_size;
                            filePointer = (char*)  malloc(numBytes);
                    n = read(fileDescriptor, filePointer, (numBytes * sizeof(int)));

                            if( n < 0 ){
                                    printf("Problem reading the file\n");
                                    exit(1);
                            }
                                    numerator = 0;
                                    numCount = 0;
                                    average = 0;

                                    while(*filePointer != NULL)
                                    {
                                    numerator += *filePointer;
                                    printf("data in array: %d\n", *filePointer);
                                    filePointer++;
                                    numCount++;
                                    }
                            average = (double) numerator / (double) numCount;
                            printf("Average: %f\n", average);

                            printf("Total Numbers: %d\n", numCount);
                    }
            }
RunFranks525
  • 163
  • 1
  • 2
  • 14
  • 1
    You say you have a binary file, but then talk of reading lines from the file. "lines" is a text concept and binary files don't have lines, just binary data. You're using the POSIX (open/read) file functions, which don't differentiate between text and binary -- files are just a sequence of bytes and it's up to you to treat those bytes as binary or ASCII text or UTF-8 text or whatever. – Chris Dodd Feb 08 '15 at 07:32
  • okay, that helps a lot. I'm just confused then how else I'm supposed to step through the array pointed to by my filePointer variable to get relevant information. I print it out and the data in each location are still just ascii values for each bit when I want there integer representation. In this case, access each locations integer to calculate an average. is it that filePointer is a pointer to type char? – RunFranks525 Feb 08 '15 at 07:48
  • You make lots of unnecessary else indentations, which makes the code less readable. Note that in all your if statements, if the condition is true, there is a return or exit so the else { is unnecessary. – Paul Ogilvie Feb 08 '15 at 12:03

2 Answers2

1

Your read() can go horribly wrong because you try to read numBytes integers but integers are not bytes. Should you have properly checked the return value from read, you would have seen as the file is not numBytes * sizeof(int) large. If the file indeed contains integers, and not strings of ASCII digits, then you can access the integers as:

int *pInt= (int *)filePointer;
while (pInt < filePointer+numBytes) { printf("%d,", *pInt); pInt++;}

If the file contains ASCII strings of digits, you need a separator to signal where one number ends and the next begins and can write:

char *s= filePointer;
while (s<filePointer+numBytes) {
    int num= 0;
    while (s<filePointer+numBytes && '0'<= *s && *s<='9') {
        num= num*10 + *s-'0';
        s++;
    }
    while (s<filePointer+numBytes && !('0'<= *s && *s<='9')) s++; // skip separator(s)
}
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • This is close, and its a big help! But right now it doesn't seem to handle negative integers. As soon as the pointer spinning through the memory locations hits a negative int the while loop condition evaluates and the rest of the integers are never hit. The number of Bytes read from the file is correct so its gotta be something down here. in my example I have 13 integers, so 52 bytes, I print this out to check and numBytes is in fact 52. Any ideas as to what might be causing this small glitch? Thanks so much! – RunFranks525 Feb 08 '15 at 22:50
  • I figured it out, I accidently had the while loop being controlled by the value pointed to not the pointer itself – RunFranks525 Feb 09 '15 at 01:44
1

If you are trying to get the each bit from the binary file( not an ASCII file ) and store it in an array, then you can use the below code to do that.

If you want to know more about the difference fo ASCII and Binary file read the post https://stackoverflow.com/a/28301127/3095460

ASCII File is also a binary file, except, the characters are encoded with ascii character set and each character take only one byte in memory. for example if you want to put an integer 10000 in a binary file it needs only 4 bytes( size of an int in binary), but a ascii file will need 5 bytes. so reading 10000 from an ascii file will have read 5 bytes to get 10000 and decode to an integer, but a binary file just we have to read 4 bytes alone.

so to read a binary file, you need a binary file editor. otherwise normal editor will decode the binary file and show something we cannot understand with our naked eyes, until you look closely into the bytes.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(){

    int fd;
    char out;
    struct stat fileStat;
    int* binArray;
    int bin_size = 0, i = 0, j = 0;

    if( (fd = open("binfile",O_RDONLY)) != -1) {
        if ( fstat(fd, &fileStat) == 0 ){
            if (fileStat.st_size != 0 &&
                ( binArray = (int*) malloc( fileStat.st_size * 8 )) != NULL) {
                for(i = 0; i < fileStat.st_size; ++i) {
                    if( read(fd, &out, sizeof(char)) == 1 ) {
                        for(j = 7; j >= 0; --j) {
                            binArray[bin_size++] = (out >> j) & 0x01;
                            printf("%d",binArray[bin_size-1]);
                        }
                    }
                }
            }
            else {
                fprintf(stderr,"Trouble Allocating Memory\n");
            }
        }
        else {
           fprintf(stderr,"Trouble pulling statistics of file\n");
        }
    }
    else {
       fprintf(stderr,"Trouble Opening the File\n");
    }
    close(fd);
}
Community
  • 1
  • 1
Sridhar Nagarajan
  • 1,085
  • 6
  • 14