How to fscanf a file into a multi-dimensional array
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
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
add a comment |
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
2
Lots of problems with the code, most notably you don't declarefile
ortest
so I'm not sure how it would even compile?
– Chris Turner
Nov 22 '18 at 16:40
1
1) [...] – No, you can't. Usefopen()
to open the file and make sure to check the returned value for errors. You might want to check the value ofargc
as well. Usefclose()
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 '18 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 '18 at 17:13
add a comment |
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
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
c arrays multidimensional-array scanf argv
edited Nov 23 '18 at 8:58
Buzzuka
asked Nov 22 '18 at 16:33
BuzzukaBuzzuka
53
53
2
Lots of problems with the code, most notably you don't declarefile
ortest
so I'm not sure how it would even compile?
– Chris Turner
Nov 22 '18 at 16:40
1
1) [...] – No, you can't. Usefopen()
to open the file and make sure to check the returned value for errors. You might want to check the value ofargc
as well. Usefclose()
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 '18 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 '18 at 17:13
add a comment |
2
Lots of problems with the code, most notably you don't declarefile
ortest
so I'm not sure how it would even compile?
– Chris Turner
Nov 22 '18 at 16:40
1
1) [...] – No, you can't. Usefopen()
to open the file and make sure to check the returned value for errors. You might want to check the value ofargc
as well. Usefclose()
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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 17:13
add a comment |
1 Answer
1
active
oldest
votes
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;
}
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
}
add a comment |
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;
}
add a comment |
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;
}
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;
}
edited Nov 23 '18 at 14:01
answered Nov 23 '18 at 11:02
xingxing
1,489288
1,489288
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
Lots of problems with the code, most notably you don't declare
file
ortest
so I'm not sure how it would even compile?– Chris Turner
Nov 22 '18 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 ofargc
as well. Usefclose()
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 '18 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 '18 at 17:13