How to fscanf a file into a multi-dimensional array











up vote
0
down vote

favorite












Scenario: I have a file in following format.



@209.161.198.176/28 209.161.198.160/28 88 : 88 80 : 80 0x11/0xFF
@203.124.178.48/28 203.124.183.192/28 123 : 123 23 : 23 0x11/0xFF
@175.54.90.240/28 209.161.199.160/28 53 : 53 21 : 21 0x11/0xFF
@175.54.96.176/28 209.161.199.160/28 123 : 123 544 : 544 0x11/0xFF
@5.220.189.176/28 5.220.186.176/28 750 : 750 123 : 123 0x11/0xFF
.../*and the file contain about 100000 lines*/


Every line can be divided into 5 sections.



//For example:
(@209.161.198.176/28) (209.161.198.160/28) (88 : 88) (80 : 80) (00x11/0xFF)


I need to read the file and store it into 5 multi-dimensional arrays for each section. The first dimension will be which line it is, the second will store its string value.



//For example, the array to store the first section might have the following structure:
[line0][@209.161.198.176/28]
[line1][@203.124.178.48/28]
[line2][@175.54.90.240/28]
...
(array[line][string])


The problem is that I always get segmentation fault and I don't know why.



Here's my current code:



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

int main(int argc, char *argv){
FILE *f;
char file1[100000][100], file2[100000][100], file3[100000][100], file4[100000][100], file5[100000][100];

char file = argv[1];
f = fopen(file,"r");
fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
printf("%c%c",fike1[0][0],file1[0][1]);
fclose(f);

return 0;
}


At line 10, I try to read the first line. At line 11, I try to print out the first 2 character of line-0's first section.



The possible problem I can think of is:



1) I can't fopen argv[1] directly like this.



2) Maybe I need to add * or & somewhere but I can't find it.



(OAO)










share|improve this question




















  • 2




    Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
    – Chris Turner
    Nov 22 at 16:40






  • 1




    1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
    – Swordfish
    Nov 22 at 16:44












  • Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
    – EsmaeelE
    Nov 22 at 17:13















up vote
0
down vote

favorite












Scenario: I have a file in following format.



@209.161.198.176/28 209.161.198.160/28 88 : 88 80 : 80 0x11/0xFF
@203.124.178.48/28 203.124.183.192/28 123 : 123 23 : 23 0x11/0xFF
@175.54.90.240/28 209.161.199.160/28 53 : 53 21 : 21 0x11/0xFF
@175.54.96.176/28 209.161.199.160/28 123 : 123 544 : 544 0x11/0xFF
@5.220.189.176/28 5.220.186.176/28 750 : 750 123 : 123 0x11/0xFF
.../*and the file contain about 100000 lines*/


Every line can be divided into 5 sections.



//For example:
(@209.161.198.176/28) (209.161.198.160/28) (88 : 88) (80 : 80) (00x11/0xFF)


I need to read the file and store it into 5 multi-dimensional arrays for each section. The first dimension will be which line it is, the second will store its string value.



//For example, the array to store the first section might have the following structure:
[line0][@209.161.198.176/28]
[line1][@203.124.178.48/28]
[line2][@175.54.90.240/28]
...
(array[line][string])


The problem is that I always get segmentation fault and I don't know why.



Here's my current code:



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

int main(int argc, char *argv){
FILE *f;
char file1[100000][100], file2[100000][100], file3[100000][100], file4[100000][100], file5[100000][100];

char file = argv[1];
f = fopen(file,"r");
fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
printf("%c%c",fike1[0][0],file1[0][1]);
fclose(f);

return 0;
}


At line 10, I try to read the first line. At line 11, I try to print out the first 2 character of line-0's first section.



The possible problem I can think of is:



1) I can't fopen argv[1] directly like this.



2) Maybe I need to add * or & somewhere but I can't find it.



(OAO)










share|improve this question




















  • 2




    Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
    – Chris Turner
    Nov 22 at 16:40






  • 1




    1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
    – Swordfish
    Nov 22 at 16:44












  • Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
    – EsmaeelE
    Nov 22 at 17:13













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Scenario: I have a file in following format.



@209.161.198.176/28 209.161.198.160/28 88 : 88 80 : 80 0x11/0xFF
@203.124.178.48/28 203.124.183.192/28 123 : 123 23 : 23 0x11/0xFF
@175.54.90.240/28 209.161.199.160/28 53 : 53 21 : 21 0x11/0xFF
@175.54.96.176/28 209.161.199.160/28 123 : 123 544 : 544 0x11/0xFF
@5.220.189.176/28 5.220.186.176/28 750 : 750 123 : 123 0x11/0xFF
.../*and the file contain about 100000 lines*/


Every line can be divided into 5 sections.



//For example:
(@209.161.198.176/28) (209.161.198.160/28) (88 : 88) (80 : 80) (00x11/0xFF)


I need to read the file and store it into 5 multi-dimensional arrays for each section. The first dimension will be which line it is, the second will store its string value.



//For example, the array to store the first section might have the following structure:
[line0][@209.161.198.176/28]
[line1][@203.124.178.48/28]
[line2][@175.54.90.240/28]
...
(array[line][string])


The problem is that I always get segmentation fault and I don't know why.



Here's my current code:



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

int main(int argc, char *argv){
FILE *f;
char file1[100000][100], file2[100000][100], file3[100000][100], file4[100000][100], file5[100000][100];

char file = argv[1];
f = fopen(file,"r");
fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
printf("%c%c",fike1[0][0],file1[0][1]);
fclose(f);

return 0;
}


At line 10, I try to read the first line. At line 11, I try to print out the first 2 character of line-0's first section.



The possible problem I can think of is:



1) I can't fopen argv[1] directly like this.



2) Maybe I need to add * or & somewhere but I can't find it.



(OAO)










share|improve this question















Scenario: I have a file in following format.



@209.161.198.176/28 209.161.198.160/28 88 : 88 80 : 80 0x11/0xFF
@203.124.178.48/28 203.124.183.192/28 123 : 123 23 : 23 0x11/0xFF
@175.54.90.240/28 209.161.199.160/28 53 : 53 21 : 21 0x11/0xFF
@175.54.96.176/28 209.161.199.160/28 123 : 123 544 : 544 0x11/0xFF
@5.220.189.176/28 5.220.186.176/28 750 : 750 123 : 123 0x11/0xFF
.../*and the file contain about 100000 lines*/


Every line can be divided into 5 sections.



//For example:
(@209.161.198.176/28) (209.161.198.160/28) (88 : 88) (80 : 80) (00x11/0xFF)


I need to read the file and store it into 5 multi-dimensional arrays for each section. The first dimension will be which line it is, the second will store its string value.



//For example, the array to store the first section might have the following structure:
[line0][@209.161.198.176/28]
[line1][@203.124.178.48/28]
[line2][@175.54.90.240/28]
...
(array[line][string])


The problem is that I always get segmentation fault and I don't know why.



Here's my current code:



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

int main(int argc, char *argv){
FILE *f;
char file1[100000][100], file2[100000][100], file3[100000][100], file4[100000][100], file5[100000][100];

char file = argv[1];
f = fopen(file,"r");
fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
printf("%c%c",fike1[0][0],file1[0][1]);
fclose(f);

return 0;
}


At line 10, I try to read the first line. At line 11, I try to print out the first 2 character of line-0's first section.



The possible problem I can think of is:



1) I can't fopen argv[1] directly like this.



2) Maybe I need to add * or & somewhere but I can't find it.



(OAO)







c arrays multidimensional-array scanf argv






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 at 8:58

























asked Nov 22 at 16:33









Buzzuka

53




53








  • 2




    Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
    – Chris Turner
    Nov 22 at 16:40






  • 1




    1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
    – Swordfish
    Nov 22 at 16:44












  • Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
    – EsmaeelE
    Nov 22 at 17:13














  • 2




    Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
    – Chris Turner
    Nov 22 at 16:40






  • 1




    1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
    – Swordfish
    Nov 22 at 16:44












  • Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
    – EsmaeelE
    Nov 22 at 17:13








2




2




Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
– Chris Turner
Nov 22 at 16:40




Lots of problems with the code, most notably you don't declare file or test so I'm not sure how it would even compile?
– Chris Turner
Nov 22 at 16:40




1




1




1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
– Swordfish
Nov 22 at 16:44






1) [...] – No, you can't. Use fopen() to open the file and make sure to check the returned value for errors. You might want to check the value of argc as well. Use fclose() when you are done with the file. Also, "%s %s %s %s %s" won't work for the format you want since "%s" reads until the next whitespace. Some of the parts like "88 : 88" you want to keep together however contain whitespace.
– Swordfish
Nov 22 at 16:44














Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
– EsmaeelE
Nov 22 at 17:13




Many error in code, use:f = fopen(argv[1],"r"); fscanf(f,"%s %s %s %s %s", file1[0], file2[0], file3[0], file4[0], file5[0]);
– EsmaeelE
Nov 22 at 17:13












1 Answer
1






active

oldest

votes

















up vote
0
down vote



accepted










fgets could be used to read each line, then parse the line for the five sections.

The first two sections are easily parsed using sscanf. The %n specifier will report the number of characters processed by the scan. Use that number as a offset for further parsing.

The third and fourth sections are difficult as they contain spaces and are separated by spaces. sscanf could be used but smaller sections would need to be parsed and concatenated into the full section.
strspn would be an option to count groups of matching characters then strncpy the counted characters.

Having a count of all the characters processed makes parsing the last section easy with sscanf.

A three dimension array keeps all the lines and sections together.

A structure would be another way of organizing the data.



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

#define LINES 1000
#define SECTIONS 5
#define SIZE 99
//lenstr so SIZE can be part of sscanf Format String
#define FS_(x) #x
#define FS(x) FS_(x)

int main( int argc, char *argv) {
char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
char *digits = "0123456789";
char *colon = " :";
int offset = 0;
int span = 0;
FILE* pf = NULL;

if ( 2 != argc) {
fprintf ( stderr, "useage:nt%s filenamen", argv[0]);
return 0;
}

if ( NULL == ( pf = fopen ( argv[1], "r"))) {
fprintf ( stderr, "could not open %sn", argv[1]);
return 0;
}

int line = 0;
while ( LINES > line && fgets ( input, sizeof input, pf)) {
span = 0;
if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
break;
}
offset += span;//skip spaces
span = strspn ( &input[offset], digits);//count digits
span += strspn ( &input[offset + span], colon);//count colon and spaces
span += strspn ( &input[offset + span], digits);//count digits
if ( ! span || SIZE < span) {
break;
}
strncpy ( record[line][each], &input[offset], span);//copy span number of characters
record[line][each][span] = 0;//zero terminate

offset += span;//advance offset to next section
}

if ( span && SIZE > span) {
sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
line++;
if ( line >= LINES) {
break;
}
}
}
}

fclose ( pf);

for ( int item = 0; item < line; ++item) {
for ( int each = 0; each < SECTIONS; ++each) {
printf ( "record[%d][%d] %sn", item, each, record[item][each]);
}
printf ( "n");
}

return 0;
}





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435086%2fhow-to-fscanf-a-file-into-a-multi-dimensional-array%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote



    accepted










    fgets could be used to read each line, then parse the line for the five sections.

    The first two sections are easily parsed using sscanf. The %n specifier will report the number of characters processed by the scan. Use that number as a offset for further parsing.

    The third and fourth sections are difficult as they contain spaces and are separated by spaces. sscanf could be used but smaller sections would need to be parsed and concatenated into the full section.
    strspn would be an option to count groups of matching characters then strncpy the counted characters.

    Having a count of all the characters processed makes parsing the last section easy with sscanf.

    A three dimension array keeps all the lines and sections together.

    A structure would be another way of organizing the data.



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

    #define LINES 1000
    #define SECTIONS 5
    #define SIZE 99
    //lenstr so SIZE can be part of sscanf Format String
    #define FS_(x) #x
    #define FS(x) FS_(x)

    int main( int argc, char *argv) {
    char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
    char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
    char *digits = "0123456789";
    char *colon = " :";
    int offset = 0;
    int span = 0;
    FILE* pf = NULL;

    if ( 2 != argc) {
    fprintf ( stderr, "useage:nt%s filenamen", argv[0]);
    return 0;
    }

    if ( NULL == ( pf = fopen ( argv[1], "r"))) {
    fprintf ( stderr, "could not open %sn", argv[1]);
    return 0;
    }

    int line = 0;
    while ( LINES > line && fgets ( input, sizeof input, pf)) {
    span = 0;
    if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
    for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
    if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
    break;
    }
    offset += span;//skip spaces
    span = strspn ( &input[offset], digits);//count digits
    span += strspn ( &input[offset + span], colon);//count colon and spaces
    span += strspn ( &input[offset + span], digits);//count digits
    if ( ! span || SIZE < span) {
    break;
    }
    strncpy ( record[line][each], &input[offset], span);//copy span number of characters
    record[line][each][span] = 0;//zero terminate

    offset += span;//advance offset to next section
    }

    if ( span && SIZE > span) {
    sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
    line++;
    if ( line >= LINES) {
    break;
    }
    }
    }
    }

    fclose ( pf);

    for ( int item = 0; item < line; ++item) {
    for ( int each = 0; each < SECTIONS; ++each) {
    printf ( "record[%d][%d] %sn", item, each, record[item][each]);
    }
    printf ( "n");
    }

    return 0;
    }





    share|improve this answer



























      up vote
      0
      down vote



      accepted










      fgets could be used to read each line, then parse the line for the five sections.

      The first two sections are easily parsed using sscanf. The %n specifier will report the number of characters processed by the scan. Use that number as a offset for further parsing.

      The third and fourth sections are difficult as they contain spaces and are separated by spaces. sscanf could be used but smaller sections would need to be parsed and concatenated into the full section.
      strspn would be an option to count groups of matching characters then strncpy the counted characters.

      Having a count of all the characters processed makes parsing the last section easy with sscanf.

      A three dimension array keeps all the lines and sections together.

      A structure would be another way of organizing the data.



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

      #define LINES 1000
      #define SECTIONS 5
      #define SIZE 99
      //lenstr so SIZE can be part of sscanf Format String
      #define FS_(x) #x
      #define FS(x) FS_(x)

      int main( int argc, char *argv) {
      char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
      char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
      char *digits = "0123456789";
      char *colon = " :";
      int offset = 0;
      int span = 0;
      FILE* pf = NULL;

      if ( 2 != argc) {
      fprintf ( stderr, "useage:nt%s filenamen", argv[0]);
      return 0;
      }

      if ( NULL == ( pf = fopen ( argv[1], "r"))) {
      fprintf ( stderr, "could not open %sn", argv[1]);
      return 0;
      }

      int line = 0;
      while ( LINES > line && fgets ( input, sizeof input, pf)) {
      span = 0;
      if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
      for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
      if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
      break;
      }
      offset += span;//skip spaces
      span = strspn ( &input[offset], digits);//count digits
      span += strspn ( &input[offset + span], colon);//count colon and spaces
      span += strspn ( &input[offset + span], digits);//count digits
      if ( ! span || SIZE < span) {
      break;
      }
      strncpy ( record[line][each], &input[offset], span);//copy span number of characters
      record[line][each][span] = 0;//zero terminate

      offset += span;//advance offset to next section
      }

      if ( span && SIZE > span) {
      sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
      line++;
      if ( line >= LINES) {
      break;
      }
      }
      }
      }

      fclose ( pf);

      for ( int item = 0; item < line; ++item) {
      for ( int each = 0; each < SECTIONS; ++each) {
      printf ( "record[%d][%d] %sn", item, each, record[item][each]);
      }
      printf ( "n");
      }

      return 0;
      }





      share|improve this answer

























        up vote
        0
        down vote



        accepted







        up vote
        0
        down vote



        accepted






        fgets could be used to read each line, then parse the line for the five sections.

        The first two sections are easily parsed using sscanf. The %n specifier will report the number of characters processed by the scan. Use that number as a offset for further parsing.

        The third and fourth sections are difficult as they contain spaces and are separated by spaces. sscanf could be used but smaller sections would need to be parsed and concatenated into the full section.
        strspn would be an option to count groups of matching characters then strncpy the counted characters.

        Having a count of all the characters processed makes parsing the last section easy with sscanf.

        A three dimension array keeps all the lines and sections together.

        A structure would be another way of organizing the data.



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

        #define LINES 1000
        #define SECTIONS 5
        #define SIZE 99
        //lenstr so SIZE can be part of sscanf Format String
        #define FS_(x) #x
        #define FS(x) FS_(x)

        int main( int argc, char *argv) {
        char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
        char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
        char *digits = "0123456789";
        char *colon = " :";
        int offset = 0;
        int span = 0;
        FILE* pf = NULL;

        if ( 2 != argc) {
        fprintf ( stderr, "useage:nt%s filenamen", argv[0]);
        return 0;
        }

        if ( NULL == ( pf = fopen ( argv[1], "r"))) {
        fprintf ( stderr, "could not open %sn", argv[1]);
        return 0;
        }

        int line = 0;
        while ( LINES > line && fgets ( input, sizeof input, pf)) {
        span = 0;
        if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
        for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
        if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
        break;
        }
        offset += span;//skip spaces
        span = strspn ( &input[offset], digits);//count digits
        span += strspn ( &input[offset + span], colon);//count colon and spaces
        span += strspn ( &input[offset + span], digits);//count digits
        if ( ! span || SIZE < span) {
        break;
        }
        strncpy ( record[line][each], &input[offset], span);//copy span number of characters
        record[line][each][span] = 0;//zero terminate

        offset += span;//advance offset to next section
        }

        if ( span && SIZE > span) {
        sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
        line++;
        if ( line >= LINES) {
        break;
        }
        }
        }
        }

        fclose ( pf);

        for ( int item = 0; item < line; ++item) {
        for ( int each = 0; each < SECTIONS; ++each) {
        printf ( "record[%d][%d] %sn", item, each, record[item][each]);
        }
        printf ( "n");
        }

        return 0;
        }





        share|improve this answer














        fgets could be used to read each line, then parse the line for the five sections.

        The first two sections are easily parsed using sscanf. The %n specifier will report the number of characters processed by the scan. Use that number as a offset for further parsing.

        The third and fourth sections are difficult as they contain spaces and are separated by spaces. sscanf could be used but smaller sections would need to be parsed and concatenated into the full section.
        strspn would be an option to count groups of matching characters then strncpy the counted characters.

        Having a count of all the characters processed makes parsing the last section easy with sscanf.

        A three dimension array keeps all the lines and sections together.

        A structure would be another way of organizing the data.



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

        #define LINES 1000
        #define SECTIONS 5
        #define SIZE 99
        //lenstr so SIZE can be part of sscanf Format String
        #define FS_(x) #x
        #define FS(x) FS_(x)

        int main( int argc, char *argv) {
        char input[SIZE + 1] = "";//SIZE + 1 to allow for zero terminator
        char record[LINES][SECTIONS][SIZE + 1] = { { { 0}}};
        char *digits = "0123456789";
        char *colon = " :";
        int offset = 0;
        int span = 0;
        FILE* pf = NULL;

        if ( 2 != argc) {
        fprintf ( stderr, "useage:nt%s filenamen", argv[0]);
        return 0;
        }

        if ( NULL == ( pf = fopen ( argv[1], "r"))) {
        fprintf ( stderr, "could not open %sn", argv[1]);
        return 0;
        }

        int line = 0;
        while ( LINES > line && fgets ( input, sizeof input, pf)) {
        span = 0;
        if ( 2 == sscanf ( input, "%"FS(SIZE)"s%"FS(SIZE)"s%n", record[line][0], record[line][1], &offset)) {
        for ( int each = 2; each < 4; ++each) {//loop for sections 2 and 3
        if ( ! ( span = strspn ( &input[offset], " "))) {//count spaces
        break;
        }
        offset += span;//skip spaces
        span = strspn ( &input[offset], digits);//count digits
        span += strspn ( &input[offset + span], colon);//count colon and spaces
        span += strspn ( &input[offset + span], digits);//count digits
        if ( ! span || SIZE < span) {
        break;
        }
        strncpy ( record[line][each], &input[offset], span);//copy span number of characters
        record[line][each][span] = 0;//zero terminate

        offset += span;//advance offset to next section
        }

        if ( span && SIZE > span) {
        sscanf ( &input[offset], "%"FS(SIZE)"s", record[line][4]);
        line++;
        if ( line >= LINES) {
        break;
        }
        }
        }
        }

        fclose ( pf);

        for ( int item = 0; item < line; ++item) {
        for ( int each = 0; each < SECTIONS; ++each) {
        printf ( "record[%d][%d] %sn", item, each, record[item][each]);
        }
        printf ( "n");
        }

        return 0;
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 23 at 14:01

























        answered Nov 23 at 11:02









        xing

        1,169278




        1,169278






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435086%2fhow-to-fscanf-a-file-into-a-multi-dimensional-array%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu