How to Read an Integer From a File in C

  1. #1

    hughng92 is offline

    Registered User


    Read integers from a file

    Hello,
    I am trying to read integer from a .txt file and then store the integers in the allocated array using malloc(). My idea is as post-obit:

    Code:

                            

    int *read_text(char *fp, int *size); FILE *fp; fp=fopen("/Users/HughNguyen/Google Drive/Notability/CSCI 2021 Lab/Project1/data/short.txt", "r"); char* array; int i, count = 0; array = malloc(len*sizeof(char)); if (fp == NULL){ size = -ane; return NULL; } else{ while(!feof(fp)){ fscanf(file, "%d", &array[count]); count++; } } for(i=0; i<count; i++){ printf(" \northward a[%d] = %d\northward",i,array[i]); } rewind(fp); fclose(fp); return 0;


    Here is my reason:
    • I open the file using fopen() and I go through the file past using fscanf() to count the number of integers in my file. Then I used malloc() to allocate an array of proper size.
    • I want to use rewind() part to go dorsum to the beginning of the file and so reads integers into my assortment. Shut the file when I am done reading all ints. I have to render a pointer to the allocated array.
    • The argument "size" in "int *read_text( char *fp, int *size)" indicates a arrow to an integer which is set to the length of the allocated array. I want to gear up a condition that if my file cannot exist opened using fopen(), then will ready my size to -1 and return Zippo.
    • This is a office of the whole program. There are iii parts: text_main text_main.c read_text.c.

    I have some errors such as:
    • Redefinition of 'fp' with a different type: 'int' vs 'FILE *'
    • Utilise of undeclared identifier 'size'
    • A parameter listing without types is only immune in a part definition

    How tin can I navigate these errors?
    Whatsoever tip will be greatly appreciated. Cheers!


  2. #2

    whiteflags is offline

    Lurking whiteflags's Avatar


    As for your errors, tin yous explain what these parameters are for?

    > int *read_text(char *fp, int *size);
    Why is the beginning named fp? That seems to be one problem.
    And why haven't yous used size?

    Well, anyway, to read a file of integers, I think the simplest code is something like this:

    Code:

    int *array = malloc( (?) * sizeof(*assortment));  if (array == NULL) {    perror("malloc"); // or any other fault handling code    return EXIT_FAILURE; }  for (int i = 0; i < count; i++) {    fscanf(fp, "%d", &array[i]); }
    This is squeamish and elementary particularly if you're certain that there will be no bug reading the file; in other words, all the text is guaranteed to be representable C integers. Unfortunately, as you lot can tell from the instance, nosotros need to know what to put for the question marker, and that is not equally direct forwards. The trouble is that using fscanf to count integers ahead of time is difficult. Ane matter standing in your fashion is the format string itself. At first glance, a format string that suppresses the assignment to the array appears that information technology might work, so you try something similar:

    Code:

    while ( (rv = fscanf(fp, "%*d")) > 0) count++;
    The trouble with this is, fscanf has to succeed at assigning something in society to return successfully (i.e. with a value of at least 1 for 1 match).

    For this reason I call back information technology is much easier to make a guess at the size of the array that yous demand, and if you know how, embiggen the assortment as you read.

    Code:

    size_t cap = 15, size = 0; void *temp = NULL; int *assortment = malloc(cap * sizeof(*array));  while (fscanf(fp, "%d", &array[size]) == one) {    size++;    if (size == cap) {       cap *= two;       temp = realloc(array, cap * sizeof(*array));       if (temp == NULL) {          perror("realloc");          gratis(temp);          return EXIT_FAILURE;       }       array = temp;    } }
    Of course, y'all could just make a really large assortment and count the size if you lot don't want to do all of this work.


  3. #three

    hughng92 is offline

    Registered User


    Hello WhiteFlags,
    Thank y'all for your response. I am happy to explicate myself.
    • First, my bad for picking the name. I should have named fp every bit "fname" as in "file proper name".
    • I think I did utilise size every bit in: char* array = malloc(*size*sizeof(char));
    • How do you put your code in the fashion in your postal service? It looks so cool!
    • At that place are sure means to do this input fashion, but I need to stick to the this open source project challenge instructions.

    Code:

    int *read_text_deltas(char *fname, int *len){   FILE *fname = fopen("text.txt", "r"); int i, count = 0; char* array = malloc(*len*sizeof(char)); if (fname == Aught){     len = -1;     return NULL; } else{     while(!feof(fname)){     fscanf(fname, "%d", &array[count]);     count++;     } } for(i=0; i<count; i++){     printf(" \due north a[%d] = %d\n",i,assortment[i]); } rewind(fname); fclose(fname); return 0;                                              }                                          


  4. #iv

    whiteflags is offline

    Lurking whiteflags's Avatar


    • Ah okay, are you sure that you didn't mean something like this instead?

      Code:

                                FILE *fp = fopen(fname, "r");
      That would brand the most sense to me, as fname would exist the path and file name cord, whereas fp is the proper name of the variable.

      You go along renaming your file variable the same equally your cord!

    • Okay, well, picayune things matter. In the original code, there was int *size, and you lot used len (a non-pointer with the incorrect name).
    • I post code in [code][/code] tags like everyone else. If your source has no other formatting, the syntax would be highlighted for you too.

    I'm still uncertain, but you might want to do something similar this.

    Code:

    count = *len; array = malloc(count * sizeof(*array));
    That is, I desire you to save *len to count so that count has a nonzero value. It makes your code work somewhat better, but I recall that what I showed, with the gradually growing array, is really what would work and what should laissez passer for the challenge.

    Also, is at that place a reason you declared the assortment equally a char*? Since we're reading integers with "%d", it's appropriate to utilize int, not char.


  5. #5

    hughng92 is offline

    Registered User


    And so actually, fname will correspond for whatever the name of the file I am going to pass in the office fopen() right?
    In my text_main.c, I have:

    Code:

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include "deltas.h"   int main(int argc, char *argv[]){   if(argc < 3){     printf("usage: %due south <format> <filename>\northward",argv[0]);     printf(" <format> is ane of\due north");     printf(" text : text ints are in the given filename\n");     printf(" int  : binary ints are in the given filename\due north");     printf(" 4bit : 4bit binary ints are in the given filename\n");     return one;   }   char *format = argv[1];   char *fname = argv[2];     int data_len = -1;   int *data_vals = NULL;   if( strcmp("text", format)==0 ){     printf("Reading text format\northward");     data_vals = read_text_deltas(fname, &data_len);   }   else if( strcmp("int", format)==0 ){     printf("Reading binary int format\n");     data_vals = read_int_deltas(fname, &data_len);   }   else if( strcmp("4bit", format)==0 ){     printf("Reading 4bit binary int format\n");     data_vals = read_4bit_deltas(fname, &data_len);   }   else{     printf("Unknown format '%south'\n",format);     return 1;   }     printf("data_len: %d\n",data_len);   printf("%4s %4s\n","#","read");   for(int i=0; i<data_len; i++){     printf("%4d %4d\northward",i,data_vals[i]);   }     free(data_vals);      render 0; }
    I am thinking "fname" may be divers in this file text_main.c. I have never used fopen() earlier and I am pretty new to C. I saw some posts online showing how to use fopen such as fopen("file.text","r").
    You are correct most my assortment declaration. I must use int.
    At present, I have narrowed down to 2 errors, thanks to your help:

    Lawmaking:

    #include <stdio.h>   int *read_text_deltas(char *fname, int *len){  FILE *fp = fopen(fname, "r"); int i, count = 0; count = *len; int* array = malloc(count *sizeof(int)); //Implicitly declaring library function 'malloc' with type 'void *(unsigned long)' if (fp == NULL){     len = &(-1); //Cannot take the address of an rvalue of blazon 'int'     render NULL; } else{     while(!feof(fp)){     fscanf(fp, "%d", &array[count]);     count++;     } } for(i=0; i<count; i++){     printf(" \n a[%d] = %d\north",i,array[i]); } rewind(fp); fclose(fp); return 0; }
    What do these two errors mean to my logics of the program?


  6. #6

    whiteflags is offline

    Lurking whiteflags's Avatar


    Well they can both be fixed with some small-scale changes. The beginning fault almost implicitly declaring malloc() can be fixed by including the header that malloc() is declared in, stdlib.h.

    The second error is near trying to take the address of a literal constant, something that you tin can't really do. To have a similar upshot, you can do *len = -1;

    However, unfortunately, with this new context that you've posted I have more to say, and it isn't really good news. It concerns what I was unsure most. You lot cannot use a negative number as an assortment size, so code similar this won't work very well.

    Code:

    count = *len; int* array = malloc(count *sizeof(int));
    You're all-time bet is to become back to my first post in this thread and try to implement i of the ideas.


  7. #7

    hughng92 is offline

    Registered User


    I see.
    Also, how do I cheque whether my file contains integers?

    Code:

                                                  if                                              (fp == Null ||(fscanf(fp,                                              "%d"                      ,&array[count])!=1) ){     count = (-1);                                              return                                              NULL;


  8. #8

    OldGuy2 is offline

    Registered User


    Personally I would showtime again, using the top-down principle where you beginning with the main function. Focus get-go on what to do and afterwards on how to do it. Something like that:

    Lawmaking:

    int main() {   int *numbers = NULL; // array that will store the numbers from the file   int num_elems = count_numbers(FILENAME);   if (num_elems > 0)   {     numbers = read_numbers(FILENAME, num_elems);     print_numbers(numbers, num_elems);     free(numbers);   }   else   {     printf("File was empty");   } }
    Next step would be to implement the functions
    1. count_numbers
    2. read_numbers
    3. print_numbers


brewerwherat.blogspot.com

Source: https://cboard.cprogramming.com/c-programming/175833-read-integers-file.html

0 Response to "How to Read an Integer From a File in C"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel