Thread: f scanf to dynamic arrays in C

  1. #1
    Registered User
    Join Date
    Oct 2021
    Posts
    15

    f scanf to dynamic arrays in C

    Hello, I have a problem whenever I try to read from a file to a dynamic array the values are just random.
    Code:
        int* aaNo;
        int* bbKod;
        int* ccPuan;
        int* ddOffset;
         aaNo=(int*)malloc(buffer * sizeof(int));
         bbKod=(int*)malloc(buffer * sizeof(int));
         ccPuan=(int*)malloc(buffer * sizeof(int));
         ddOffset=(int*)malloc(buffer * sizeof(int));
        //int aaNo[buffer],bbKod[buffer],ccPuan[buffer],ddOffset[buffer];
        int line[100],o=0;
        while(fgets(line,sizeof(line),veri))
        {
            fscanf(veri,"%d %d %d %d",&aaNo[o],&bbKod[o],&ccPuan[o],&ddOffset[o]);
            o++;
        }
    this is the code and here is the file I want to read:



    Why do I get random numbers? Pls help.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Please attach your text file as text, not a broken inline picture.

    What is 'buffer' initialised to prior to calling malloc?

    What stops 'o' from running past the end of allocated space?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2021
    Posts
    15
    Quote Originally Posted by Salem View Post
    Please attach your text file as text, not a broken inline picture.

    What is 'buffer' initialised to prior to calling malloc?

    What stops 'o' from running past the end of allocated space?

    It is a .dat file I can just show you some lines of it:
    9 2 34 4225420
    7 4 24 42205436
    0 3 62 4225452
    0 1 45 4225468
    9 1 61 4225484
    4 1 42 4225500
    8 1 91 4225516
    8 2 53 4225532
    6 2 21 4225548
    4 5 95 4225564
    5 5 71 4225580
    5 2 12 4225596

    and here is what buffer is(it is just a variable that counts how many lines is in the file so I can dynamically allocate memory for that):
    Code:
     int buffer=0;
        char c;
        for (c = getc(veri); c != EOF; c = getc(veri))
            {
    
    
            if (c == '\n') 
                buffer = buffer + 1;
            }

  4. #4
    Registered User
    Join Date
    Oct 2021
    Posts
    15
    I fixed my code
    Code:
    int o=0;
        while(fscanf(veri,"%d %d %d %d",&aaNo[o],&bbKod[o],&ccPuan[o],&ddOffset[o]) == 4)
        {
            o++;
        }
    to this. Because apperanetly it was unnecesary to use fgets and fscanf at the same time. But it still produces random numbers.

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    Since you've already read through the whole file to determine the number of lines, you need to reset it back to the beginning to read the numbers. You can close it and re-open it, use fseek, or use the convenient rewind function. You should also use a struct to hold the information in a single array.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    #define INPUT_FILE "data.txt"
     
    typedef struct Record
    {
        int no, kod, puan, offset;
    } Record;
     
    int main()
    {
        FILE *fin = fopen(INPUT_FILE, "r");
        if (!fin)
        {
            printf("Error: cannot open input file %s\n", INPUT_FILE);
            exit(EXIT_FAILURE);
        }
     
        int lines = 0;
        for (int a, b, c, d; fscanf(fin, "%d%d%d%d", &a, &b, &c, &d) == 4; ++lines)
            ;
     
        Record *recs = malloc(lines * sizeof *recs);
     
        rewind(fin);
     
        for (int i = 0; i < lines && fscanf(fin, "%d%d%d%d", &recs[i].no, &recs[i].kod, &recs[i].puan, &recs[i].offset) == 4; ++i)
            ;
     
        fclose(fin);
     
        for (int i = 0; i < lines; ++i)
             printf("%d %d %d %d\n", recs[i].no, recs[i].kod, recs[i].puan, recs[i].offset);
     
        free(recs);
     
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  6. #6
    Registered User
    Join Date
    Oct 2021
    Posts
    15
    Thank you so much man. I can't believe all my prob was fseek. Thank you.

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    1,628
    No problem. Note that you didn't use the fgets followed by *scanf idiom correctly. The *scanf shouldn't have been an fscanf but an sscanf, taking input from the line you read with fgets. One good thing about this technique is that you can ensure the lines have the correct number of values, something like the following code, which will consider any of these lines as an error:
    1 2 3
    1 2 3 4 5
    1 2 x 3 4
    1 2 3 4 x
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define INPUT_FILE "data.txt"
     
    typedef struct Record {
        int no, kod, puan, offset;
    } Record;
     
    int main() {
        FILE *fin = fopen(INPUT_FILE, "r");
        if (!fin) {
            printf("Error: cannot open input file %s\n", INPUT_FILE);
            exit(EXIT_FAILURE);
        }
     
        int rec_count = 0;
     
        char line[1024];
        for (int line_no = 0; fgets(line, sizeof line, fin); ++line_no) {
            if (line[strspn(line, " \t\n")] == '\0')
                continue; // skip blank lines
            // ensure line has exactly 4 integers
            int a, b, c, d;
            char ch;
            if (sscanf(line, "%d%d%d%d %c", &a, &b, &c, &d, &ch) != 4)
            {
                printf("Error: bad line #%d:\n%s\n", line_no + 1, line);
                exit(EXIT_FAILURE);
            }
            ++rec_count;
        }
     
        Record *recs = malloc(rec_count * sizeof *recs);
     
        rewind(fin);
     
        for (int i = 0;
             i < rec_count && fscanf(fin, "%d%d%d%d", &recs[i].no,
                                                      &recs[i].kod,
                                                      &recs[i].puan,
                                                      &recs[i].offset) == 4;
             ++i)
            ;
     
        fclose(fin);
     
        for (int i = 0; i < rec_count; ++i)
             printf("%d %d %d %d\n", recs[i].no,
                                     recs[i].kod,
                                     recs[i].puan,
                                     recs[i].offset);
     
        free(recs);
     
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  8. #8
    Registered User
    Join Date
    Oct 2021
    Posts
    15
    Hey John sorry for disturbing you again. When I try to do
    Code:
     Record *recs = malloc(rec_count * sizeof*recs);
    I get the error: C:\Users\Berk\Desktop\Codes\Dense Indexing\main.c|278|error: 'recs' undeclared (first use in this function); did you mean 'gets'?|

    Can you help me with that?

  9. #9
    Registered User
    Join Date
    Oct 2021
    Posts
    15
    OK I found my own mistake. Sorry for bothering.

  10. #10
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by fleafy View Post
    and here is what buffer is(it is just a variable that counts how many lines is in the file so I can dynamically allocate memory for that):
    Code:
     int buffer=0;
        char c;
        for (c = getc(veri); c != EOF; c = getc(veri))
            {
    
    
            if (c == '\n') 
                buffer = buffer + 1;
            }
    Just a note that getc() returns an int, so c should be declared as int c;:
    Code:
     int buffer=0;
        int c;
        for (c = getc(veri); c != EOF; c = getc(veri))
            {
    
            if (c == '\n') 
                buffer = buffer + 1;
            }
    Otherwise the program may not be able to distinguish between EOF and a valid character.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 12-03-2011, 02:26 PM
  2. scanf "%as" (dynamic char arrays)
    By brightmatter in forum C Programming
    Replies: 10
    Last Post: 03-06-2010, 12:05 AM
  3. Scanf and Dynamic arrays
    By no_one_knows in forum C++ Programming
    Replies: 4
    Last Post: 06-17-2009, 04:04 PM
  4. Replies: 16
    Last Post: 01-01-2008, 04:07 PM
  5. Scanf and 2D arrays
    By Killahkode in forum C Programming
    Replies: 2
    Last Post: 09-27-2006, 09:28 PM

Tags for this Thread