Search code examples
carraystext-filesfgetc

Reading numbers from a file into an array


I would like to read 3-digit-numbers with spaces inbetween from a file with the fgetc()-command and put them into an array, which is not currently working, as the resulting array has completely different objects in it. What am I doing wrong? (I used a file with "107 313 052 614" in it, resulting in the output "5435 5641 5380 5942")

My Code:

#include<stdio.h>
#include<stdlib.h>


void print_array(int* arrayp, int lengthp){
    int i;
    for(i=0;i<lengthp;i++){
        printf("%i ", arrayp[i]);
    }
    return;
}

int main(){
    int length=1;
    int i;
    FILE *fp1;
    fp1 = fopen("durations.txt", "r");
    fgetc(fp1);fgetc(fp1);fgetc(fp1);
    while(fgetc(fp1)!=EOF){
        length++;
        fgetc(fp1);
        fgetc(fp1);
        fgetc(fp1);
    }
    fclose(fp1);
    int* list = (int*) malloc(sizeof(int)*length);
    FILE *fp2;
    fp2 = fopen("durations.txt", "r");
    for(i=0;i<length;i++){
        list[i]=0;
        list[i]+=100*(fgetc(fp2));
        list[i]+=10*(fgetc(fp2));
        list[i]+=(fgetc(fp2));
        fgetc(fp2);
    }
    fclose(fp2);
    print_array(list, length);
    return 0;
}

Solution

  • The characters that are used to store digits in a "readable" file are not "numbers". The most popular encoding is ascii character encoding, ex. the 1 digit is represented with the number 49 in decimal.

    Because the 0, 1, 2 ... 9 digits in ascii encoding are encoded in increasing order, you can just substract 48 (ie. '0' character) to convert a digit character to it's machine format Just - '0'.

    Change you loop into:

    for(i=0;i<length;i++){
        list[i]=0;
        list[i]+=100*(fgetc(fp2) - '0');
        list[i]+=10*(fgetc(fp2) - '0');
        list[i]+=(fgetc(fp2) - '0');
        fgetc(fp2);
    }
    

    This also explains the current output of your program. If you don't substract '0' from the numbers, then for example for 107 you get:

    100 * '1' + 10 * '0' + '7' =
    100 * 49  + 10 * 48  + 55  =
    5435
    

    The 49, 48 and 55 are decimal values for digits 1, 0 and 7 in ascii table.