Read in the contents of a tab delimited text file and save into a single array in C
I am trying to read in the contents of a file using command line arguments to read the file and then store all contents of the file into a single array.
Keep in the mind, the file being read in is actually a matrix with the first row being an integer value designating the square size of the matrix and the following rows and columns being the matrix.
so far I have been able to dynamically allocate memory and then read the contents of the file using fgets. I am kind of stumped when it comes to storing the contents into a single array to access later. I tried using a double variable to hold the parsed contents of the 2nd while loop but when printed to the terminal it only gave me the last variable in the file.
I have attempted using strdup to make a copy of the string but am running into an error that says a value of type char cannot be stored in an entity of type char
here is my code.
If someone could help me, I would be very grateful.
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char **argv){ //char **argv will be used to read the input file
int i,j,k,l,m,nn;
long size;
double mat;
char *buff;
char n[100];
char *file = argv[1];
long len =0;
int h =0;
FILE *output; // need to declare the output file
FILE *f =fopen(file, "rb+"); //utilize argv to read in file, will read file in as binary file to obtain ASCII
fseek(f, 0L, SEEK_END); //Want to determine the size of the file to create a buffer
size = ftell(f); //Will seek to the end of the file, declare that position as the size
rewind(f); //Will rewind to the beginning of the file
buff = (char *)malloc(size); //Declare the buffer size from fseek
//Will read in and print out the contents of the file using fgets and printf
while(fgets(buff,size - 1,f) != NULL){
printf( "%sn", buff);
}
rewind(f);
while(fscanf(f, "%lf", &mat) ==1){
buff[h] = _strdup(n);
h++;
}
printf("matrix stored is %cn",mat);
c arrays text-files
|
show 1 more comment
I am trying to read in the contents of a file using command line arguments to read the file and then store all contents of the file into a single array.
Keep in the mind, the file being read in is actually a matrix with the first row being an integer value designating the square size of the matrix and the following rows and columns being the matrix.
so far I have been able to dynamically allocate memory and then read the contents of the file using fgets. I am kind of stumped when it comes to storing the contents into a single array to access later. I tried using a double variable to hold the parsed contents of the 2nd while loop but when printed to the terminal it only gave me the last variable in the file.
I have attempted using strdup to make a copy of the string but am running into an error that says a value of type char cannot be stored in an entity of type char
here is my code.
If someone could help me, I would be very grateful.
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char **argv){ //char **argv will be used to read the input file
int i,j,k,l,m,nn;
long size;
double mat;
char *buff;
char n[100];
char *file = argv[1];
long len =0;
int h =0;
FILE *output; // need to declare the output file
FILE *f =fopen(file, "rb+"); //utilize argv to read in file, will read file in as binary file to obtain ASCII
fseek(f, 0L, SEEK_END); //Want to determine the size of the file to create a buffer
size = ftell(f); //Will seek to the end of the file, declare that position as the size
rewind(f); //Will rewind to the beginning of the file
buff = (char *)malloc(size); //Declare the buffer size from fseek
//Will read in and print out the contents of the file using fgets and printf
while(fgets(buff,size - 1,f) != NULL){
printf( "%sn", buff);
}
rewind(f);
while(fscanf(f, "%lf", &mat) ==1){
buff[h] = _strdup(n);
h++;
}
printf("matrix stored is %cn",mat);
c arrays text-files
2
You know you can't store an entire matrix in a singledouble
variable?
– Osiris
Nov 18 '18 at 2:27
1
strtok()
andstrtod()
are your friends.
– Shawn
Nov 18 '18 at 2:32
1
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
1
There are a number of ways to do it. Read a line at a time withfgets
and then usestrtod
(utilizing the*endptr
parameter) and scanning forward with either a simple loop orstrchr
to the next','
(or separator char), add1
to the pointer, and repeat. Alternatively tokenize the line withstrtok
with",n"
as your delimiters callingstrtod
on the return fromstrtok
within a loop. (you can also usesscanf
with the%n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.
– David C. Rankin
Nov 18 '18 at 2:43
1
size = ftell(f);
reports the file length.while(fgets(buff,size - 1,f) != NULL)
only reads a line.
– chux
Nov 18 '18 at 3:53
|
show 1 more comment
I am trying to read in the contents of a file using command line arguments to read the file and then store all contents of the file into a single array.
Keep in the mind, the file being read in is actually a matrix with the first row being an integer value designating the square size of the matrix and the following rows and columns being the matrix.
so far I have been able to dynamically allocate memory and then read the contents of the file using fgets. I am kind of stumped when it comes to storing the contents into a single array to access later. I tried using a double variable to hold the parsed contents of the 2nd while loop but when printed to the terminal it only gave me the last variable in the file.
I have attempted using strdup to make a copy of the string but am running into an error that says a value of type char cannot be stored in an entity of type char
here is my code.
If someone could help me, I would be very grateful.
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char **argv){ //char **argv will be used to read the input file
int i,j,k,l,m,nn;
long size;
double mat;
char *buff;
char n[100];
char *file = argv[1];
long len =0;
int h =0;
FILE *output; // need to declare the output file
FILE *f =fopen(file, "rb+"); //utilize argv to read in file, will read file in as binary file to obtain ASCII
fseek(f, 0L, SEEK_END); //Want to determine the size of the file to create a buffer
size = ftell(f); //Will seek to the end of the file, declare that position as the size
rewind(f); //Will rewind to the beginning of the file
buff = (char *)malloc(size); //Declare the buffer size from fseek
//Will read in and print out the contents of the file using fgets and printf
while(fgets(buff,size - 1,f) != NULL){
printf( "%sn", buff);
}
rewind(f);
while(fscanf(f, "%lf", &mat) ==1){
buff[h] = _strdup(n);
h++;
}
printf("matrix stored is %cn",mat);
c arrays text-files
I am trying to read in the contents of a file using command line arguments to read the file and then store all contents of the file into a single array.
Keep in the mind, the file being read in is actually a matrix with the first row being an integer value designating the square size of the matrix and the following rows and columns being the matrix.
so far I have been able to dynamically allocate memory and then read the contents of the file using fgets. I am kind of stumped when it comes to storing the contents into a single array to access later. I tried using a double variable to hold the parsed contents of the 2nd while loop but when printed to the terminal it only gave me the last variable in the file.
I have attempted using strdup to make a copy of the string but am running into an error that says a value of type char cannot be stored in an entity of type char
here is my code.
If someone could help me, I would be very grateful.
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char **argv){ //char **argv will be used to read the input file
int i,j,k,l,m,nn;
long size;
double mat;
char *buff;
char n[100];
char *file = argv[1];
long len =0;
int h =0;
FILE *output; // need to declare the output file
FILE *f =fopen(file, "rb+"); //utilize argv to read in file, will read file in as binary file to obtain ASCII
fseek(f, 0L, SEEK_END); //Want to determine the size of the file to create a buffer
size = ftell(f); //Will seek to the end of the file, declare that position as the size
rewind(f); //Will rewind to the beginning of the file
buff = (char *)malloc(size); //Declare the buffer size from fseek
//Will read in and print out the contents of the file using fgets and printf
while(fgets(buff,size - 1,f) != NULL){
printf( "%sn", buff);
}
rewind(f);
while(fscanf(f, "%lf", &mat) ==1){
buff[h] = _strdup(n);
h++;
}
printf("matrix stored is %cn",mat);
c arrays text-files
c arrays text-files
edited Nov 18 '18 at 2:31
paulsm4
78k9100126
78k9100126
asked Nov 18 '18 at 2:24
KolacheMasterKolacheMaster
319
319
2
You know you can't store an entire matrix in a singledouble
variable?
– Osiris
Nov 18 '18 at 2:27
1
strtok()
andstrtod()
are your friends.
– Shawn
Nov 18 '18 at 2:32
1
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
1
There are a number of ways to do it. Read a line at a time withfgets
and then usestrtod
(utilizing the*endptr
parameter) and scanning forward with either a simple loop orstrchr
to the next','
(or separator char), add1
to the pointer, and repeat. Alternatively tokenize the line withstrtok
with",n"
as your delimiters callingstrtod
on the return fromstrtok
within a loop. (you can also usesscanf
with the%n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.
– David C. Rankin
Nov 18 '18 at 2:43
1
size = ftell(f);
reports the file length.while(fgets(buff,size - 1,f) != NULL)
only reads a line.
– chux
Nov 18 '18 at 3:53
|
show 1 more comment
2
You know you can't store an entire matrix in a singledouble
variable?
– Osiris
Nov 18 '18 at 2:27
1
strtok()
andstrtod()
are your friends.
– Shawn
Nov 18 '18 at 2:32
1
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
1
There are a number of ways to do it. Read a line at a time withfgets
and then usestrtod
(utilizing the*endptr
parameter) and scanning forward with either a simple loop orstrchr
to the next','
(or separator char), add1
to the pointer, and repeat. Alternatively tokenize the line withstrtok
with",n"
as your delimiters callingstrtod
on the return fromstrtok
within a loop. (you can also usesscanf
with the%n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.
– David C. Rankin
Nov 18 '18 at 2:43
1
size = ftell(f);
reports the file length.while(fgets(buff,size - 1,f) != NULL)
only reads a line.
– chux
Nov 18 '18 at 3:53
2
2
You know you can't store an entire matrix in a single
double
variable?– Osiris
Nov 18 '18 at 2:27
You know you can't store an entire matrix in a single
double
variable?– Osiris
Nov 18 '18 at 2:27
1
1
strtok()
and strtod()
are your friends.– Shawn
Nov 18 '18 at 2:32
strtok()
and strtod()
are your friends.– Shawn
Nov 18 '18 at 2:32
1
1
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
1
1
There are a number of ways to do it. Read a line at a time with
fgets
and then use strtod
(utilizing the *endptr
parameter) and scanning forward with either a simple loop or strchr
to the next ','
(or separator char), add 1
to the pointer, and repeat. Alternatively tokenize the line with strtok
with ",n"
as your delimiters calling strtod
on the return from strtok
within a loop. (you can also use sscanf
with the %n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.– David C. Rankin
Nov 18 '18 at 2:43
There are a number of ways to do it. Read a line at a time with
fgets
and then use strtod
(utilizing the *endptr
parameter) and scanning forward with either a simple loop or strchr
to the next ','
(or separator char), add 1
to the pointer, and repeat. Alternatively tokenize the line with strtok
with ",n"
as your delimiters calling strtod
on the return from strtok
within a loop. (you can also use sscanf
with the %n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.– David C. Rankin
Nov 18 '18 at 2:43
1
1
size = ftell(f);
reports the file length. while(fgets(buff,size - 1,f) != NULL)
only reads a line.– chux
Nov 18 '18 at 3:53
size = ftell(f);
reports the file length. while(fgets(buff,size - 1,f) != NULL)
only reads a line.– chux
Nov 18 '18 at 3:53
|
show 1 more comment
1 Answer
1
active
oldest
votes
Here's an example:
/*
* EXAMPLE FILE:
* 3,3
* 1,2,3
* 4,5,6
* 7,8,9
*
* EXAMPLE OUTPUT:
* #/rows=3, #/columns=3
* 1.000000, 2.000000, 3.000000
* 4.000000, 5.000000, 6.000000
* 7.000000, 8.000000, 9.000000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 100
#define DELIMITER ","
void print_matrix (int nrows, int ncols, double **mat) {
int i, j;
printf("#/rows=%d, #/columns=%dn", nrows, ncols);
for (i=0; i < nrows; i++) {
for (j=0; j < ncols-1; j++) {
printf("%lf, ", mat[i][j]);
}
printf("%lfn", mat[i][j]);
}
}
int main(int argc, char *argv) {
FILE *fp = NULL;
int iret = 1, n = 0, nrows, ncols;
double **mat, d;
char *s, line[MAXLINE], *endptr;
int i, j;
/* Read .csv filepath from cmd-line */
if (argc < 2) {
printf ("USAGE: app <fname>n");
goto the_end;
}
/* Open file */
if (!(fp = fopen (argv[1], "r"))) {
printf ("File open(%s) failed: errno= %dn",
argv[1], errno);
goto the_end;
}
/* Read matrix dimensions */
iret = fscanf(fp, "%d,%d", &ncols, &nrows);
if (iret != 2) {
printf ("Unable to read file dimensions, iret= %d, expected 2n",
iret);
goto the_end;
}
/* Flush the extraneous newline left in the read buffer after fscanf()... */
fgetc(fp);
/* Allocate space for our matrix */
mat = (double **)malloc(sizeof(double *)*nrows);
if (!mat) {
printf ("Memory allocation error @matrix, errno=%d: exiting progamn",
errno);
goto the_end;
}
for (i=0; i < nrows; i++) {
mat[i] = malloc(sizeof(double)*ncols);
if (!mat[i]) {
printf ("Memory allocation error @matrix[%d], errno=%d: exiting progamn",
i, errno);
goto the_end;
}
}
/* Populate the matrix */
for (i=0; i < nrows; i++) {
++n;
s = fgets(line, MAXLINE, fp);
if (s == NULL) {
printf ("fgets read error, line %d, errno=%d: exiting programn",
n, errno);
goto the_end;
}
s = strtok(line, DELIMITER);
for (j=0; j < ncols; j++) {
d = strtod(s, &endptr);
if (s == endptr) {
printf ("strtod(%s) conversion error, errno %d: exiting programn",
s, errno);
goto the_end;
}
mat[i][j] = d;
s = strtok(NULL, DELIMITER);
}
}
/* Print the matrix */
print_matrix (nrows, ncols, mat);
/* Set "OK" status */
iret = 0;
the_end:
if (fp)
fclose(fp);
printf("Done: status=%d (%s)n",
iret,
(iret == 0) ? "Status: OK" : "Status: FAIL");
return iret;
}
Nice example but I think thefree
s are missing.
– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try thismat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!
– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
Yes. The way C works, a 2-d array likea
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.
– paulsm4
Nov 19 '18 at 17:58
|
show 2 more comments
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%2f53357358%2fread-in-the-contents-of-a-tab-delimited-text-file-and-save-into-a-single-array-i%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
Here's an example:
/*
* EXAMPLE FILE:
* 3,3
* 1,2,3
* 4,5,6
* 7,8,9
*
* EXAMPLE OUTPUT:
* #/rows=3, #/columns=3
* 1.000000, 2.000000, 3.000000
* 4.000000, 5.000000, 6.000000
* 7.000000, 8.000000, 9.000000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 100
#define DELIMITER ","
void print_matrix (int nrows, int ncols, double **mat) {
int i, j;
printf("#/rows=%d, #/columns=%dn", nrows, ncols);
for (i=0; i < nrows; i++) {
for (j=0; j < ncols-1; j++) {
printf("%lf, ", mat[i][j]);
}
printf("%lfn", mat[i][j]);
}
}
int main(int argc, char *argv) {
FILE *fp = NULL;
int iret = 1, n = 0, nrows, ncols;
double **mat, d;
char *s, line[MAXLINE], *endptr;
int i, j;
/* Read .csv filepath from cmd-line */
if (argc < 2) {
printf ("USAGE: app <fname>n");
goto the_end;
}
/* Open file */
if (!(fp = fopen (argv[1], "r"))) {
printf ("File open(%s) failed: errno= %dn",
argv[1], errno);
goto the_end;
}
/* Read matrix dimensions */
iret = fscanf(fp, "%d,%d", &ncols, &nrows);
if (iret != 2) {
printf ("Unable to read file dimensions, iret= %d, expected 2n",
iret);
goto the_end;
}
/* Flush the extraneous newline left in the read buffer after fscanf()... */
fgetc(fp);
/* Allocate space for our matrix */
mat = (double **)malloc(sizeof(double *)*nrows);
if (!mat) {
printf ("Memory allocation error @matrix, errno=%d: exiting progamn",
errno);
goto the_end;
}
for (i=0; i < nrows; i++) {
mat[i] = malloc(sizeof(double)*ncols);
if (!mat[i]) {
printf ("Memory allocation error @matrix[%d], errno=%d: exiting progamn",
i, errno);
goto the_end;
}
}
/* Populate the matrix */
for (i=0; i < nrows; i++) {
++n;
s = fgets(line, MAXLINE, fp);
if (s == NULL) {
printf ("fgets read error, line %d, errno=%d: exiting programn",
n, errno);
goto the_end;
}
s = strtok(line, DELIMITER);
for (j=0; j < ncols; j++) {
d = strtod(s, &endptr);
if (s == endptr) {
printf ("strtod(%s) conversion error, errno %d: exiting programn",
s, errno);
goto the_end;
}
mat[i][j] = d;
s = strtok(NULL, DELIMITER);
}
}
/* Print the matrix */
print_matrix (nrows, ncols, mat);
/* Set "OK" status */
iret = 0;
the_end:
if (fp)
fclose(fp);
printf("Done: status=%d (%s)n",
iret,
(iret == 0) ? "Status: OK" : "Status: FAIL");
return iret;
}
Nice example but I think thefree
s are missing.
– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try thismat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!
– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
Yes. The way C works, a 2-d array likea
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.
– paulsm4
Nov 19 '18 at 17:58
|
show 2 more comments
Here's an example:
/*
* EXAMPLE FILE:
* 3,3
* 1,2,3
* 4,5,6
* 7,8,9
*
* EXAMPLE OUTPUT:
* #/rows=3, #/columns=3
* 1.000000, 2.000000, 3.000000
* 4.000000, 5.000000, 6.000000
* 7.000000, 8.000000, 9.000000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 100
#define DELIMITER ","
void print_matrix (int nrows, int ncols, double **mat) {
int i, j;
printf("#/rows=%d, #/columns=%dn", nrows, ncols);
for (i=0; i < nrows; i++) {
for (j=0; j < ncols-1; j++) {
printf("%lf, ", mat[i][j]);
}
printf("%lfn", mat[i][j]);
}
}
int main(int argc, char *argv) {
FILE *fp = NULL;
int iret = 1, n = 0, nrows, ncols;
double **mat, d;
char *s, line[MAXLINE], *endptr;
int i, j;
/* Read .csv filepath from cmd-line */
if (argc < 2) {
printf ("USAGE: app <fname>n");
goto the_end;
}
/* Open file */
if (!(fp = fopen (argv[1], "r"))) {
printf ("File open(%s) failed: errno= %dn",
argv[1], errno);
goto the_end;
}
/* Read matrix dimensions */
iret = fscanf(fp, "%d,%d", &ncols, &nrows);
if (iret != 2) {
printf ("Unable to read file dimensions, iret= %d, expected 2n",
iret);
goto the_end;
}
/* Flush the extraneous newline left in the read buffer after fscanf()... */
fgetc(fp);
/* Allocate space for our matrix */
mat = (double **)malloc(sizeof(double *)*nrows);
if (!mat) {
printf ("Memory allocation error @matrix, errno=%d: exiting progamn",
errno);
goto the_end;
}
for (i=0; i < nrows; i++) {
mat[i] = malloc(sizeof(double)*ncols);
if (!mat[i]) {
printf ("Memory allocation error @matrix[%d], errno=%d: exiting progamn",
i, errno);
goto the_end;
}
}
/* Populate the matrix */
for (i=0; i < nrows; i++) {
++n;
s = fgets(line, MAXLINE, fp);
if (s == NULL) {
printf ("fgets read error, line %d, errno=%d: exiting programn",
n, errno);
goto the_end;
}
s = strtok(line, DELIMITER);
for (j=0; j < ncols; j++) {
d = strtod(s, &endptr);
if (s == endptr) {
printf ("strtod(%s) conversion error, errno %d: exiting programn",
s, errno);
goto the_end;
}
mat[i][j] = d;
s = strtok(NULL, DELIMITER);
}
}
/* Print the matrix */
print_matrix (nrows, ncols, mat);
/* Set "OK" status */
iret = 0;
the_end:
if (fp)
fclose(fp);
printf("Done: status=%d (%s)n",
iret,
(iret == 0) ? "Status: OK" : "Status: FAIL");
return iret;
}
Nice example but I think thefree
s are missing.
– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try thismat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!
– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
Yes. The way C works, a 2-d array likea
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.
– paulsm4
Nov 19 '18 at 17:58
|
show 2 more comments
Here's an example:
/*
* EXAMPLE FILE:
* 3,3
* 1,2,3
* 4,5,6
* 7,8,9
*
* EXAMPLE OUTPUT:
* #/rows=3, #/columns=3
* 1.000000, 2.000000, 3.000000
* 4.000000, 5.000000, 6.000000
* 7.000000, 8.000000, 9.000000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 100
#define DELIMITER ","
void print_matrix (int nrows, int ncols, double **mat) {
int i, j;
printf("#/rows=%d, #/columns=%dn", nrows, ncols);
for (i=0; i < nrows; i++) {
for (j=0; j < ncols-1; j++) {
printf("%lf, ", mat[i][j]);
}
printf("%lfn", mat[i][j]);
}
}
int main(int argc, char *argv) {
FILE *fp = NULL;
int iret = 1, n = 0, nrows, ncols;
double **mat, d;
char *s, line[MAXLINE], *endptr;
int i, j;
/* Read .csv filepath from cmd-line */
if (argc < 2) {
printf ("USAGE: app <fname>n");
goto the_end;
}
/* Open file */
if (!(fp = fopen (argv[1], "r"))) {
printf ("File open(%s) failed: errno= %dn",
argv[1], errno);
goto the_end;
}
/* Read matrix dimensions */
iret = fscanf(fp, "%d,%d", &ncols, &nrows);
if (iret != 2) {
printf ("Unable to read file dimensions, iret= %d, expected 2n",
iret);
goto the_end;
}
/* Flush the extraneous newline left in the read buffer after fscanf()... */
fgetc(fp);
/* Allocate space for our matrix */
mat = (double **)malloc(sizeof(double *)*nrows);
if (!mat) {
printf ("Memory allocation error @matrix, errno=%d: exiting progamn",
errno);
goto the_end;
}
for (i=0; i < nrows; i++) {
mat[i] = malloc(sizeof(double)*ncols);
if (!mat[i]) {
printf ("Memory allocation error @matrix[%d], errno=%d: exiting progamn",
i, errno);
goto the_end;
}
}
/* Populate the matrix */
for (i=0; i < nrows; i++) {
++n;
s = fgets(line, MAXLINE, fp);
if (s == NULL) {
printf ("fgets read error, line %d, errno=%d: exiting programn",
n, errno);
goto the_end;
}
s = strtok(line, DELIMITER);
for (j=0; j < ncols; j++) {
d = strtod(s, &endptr);
if (s == endptr) {
printf ("strtod(%s) conversion error, errno %d: exiting programn",
s, errno);
goto the_end;
}
mat[i][j] = d;
s = strtok(NULL, DELIMITER);
}
}
/* Print the matrix */
print_matrix (nrows, ncols, mat);
/* Set "OK" status */
iret = 0;
the_end:
if (fp)
fclose(fp);
printf("Done: status=%d (%s)n",
iret,
(iret == 0) ? "Status: OK" : "Status: FAIL");
return iret;
}
Here's an example:
/*
* EXAMPLE FILE:
* 3,3
* 1,2,3
* 4,5,6
* 7,8,9
*
* EXAMPLE OUTPUT:
* #/rows=3, #/columns=3
* 1.000000, 2.000000, 3.000000
* 4.000000, 5.000000, 6.000000
* 7.000000, 8.000000, 9.000000
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define MAXLINE 100
#define DELIMITER ","
void print_matrix (int nrows, int ncols, double **mat) {
int i, j;
printf("#/rows=%d, #/columns=%dn", nrows, ncols);
for (i=0; i < nrows; i++) {
for (j=0; j < ncols-1; j++) {
printf("%lf, ", mat[i][j]);
}
printf("%lfn", mat[i][j]);
}
}
int main(int argc, char *argv) {
FILE *fp = NULL;
int iret = 1, n = 0, nrows, ncols;
double **mat, d;
char *s, line[MAXLINE], *endptr;
int i, j;
/* Read .csv filepath from cmd-line */
if (argc < 2) {
printf ("USAGE: app <fname>n");
goto the_end;
}
/* Open file */
if (!(fp = fopen (argv[1], "r"))) {
printf ("File open(%s) failed: errno= %dn",
argv[1], errno);
goto the_end;
}
/* Read matrix dimensions */
iret = fscanf(fp, "%d,%d", &ncols, &nrows);
if (iret != 2) {
printf ("Unable to read file dimensions, iret= %d, expected 2n",
iret);
goto the_end;
}
/* Flush the extraneous newline left in the read buffer after fscanf()... */
fgetc(fp);
/* Allocate space for our matrix */
mat = (double **)malloc(sizeof(double *)*nrows);
if (!mat) {
printf ("Memory allocation error @matrix, errno=%d: exiting progamn",
errno);
goto the_end;
}
for (i=0; i < nrows; i++) {
mat[i] = malloc(sizeof(double)*ncols);
if (!mat[i]) {
printf ("Memory allocation error @matrix[%d], errno=%d: exiting progamn",
i, errno);
goto the_end;
}
}
/* Populate the matrix */
for (i=0; i < nrows; i++) {
++n;
s = fgets(line, MAXLINE, fp);
if (s == NULL) {
printf ("fgets read error, line %d, errno=%d: exiting programn",
n, errno);
goto the_end;
}
s = strtok(line, DELIMITER);
for (j=0; j < ncols; j++) {
d = strtod(s, &endptr);
if (s == endptr) {
printf ("strtod(%s) conversion error, errno %d: exiting programn",
s, errno);
goto the_end;
}
mat[i][j] = d;
s = strtok(NULL, DELIMITER);
}
}
/* Print the matrix */
print_matrix (nrows, ncols, mat);
/* Set "OK" status */
iret = 0;
the_end:
if (fp)
fclose(fp);
printf("Done: status=%d (%s)n",
iret,
(iret == 0) ? "Status: OK" : "Status: FAIL");
return iret;
}
edited Nov 18 '18 at 5:02
answered Nov 18 '18 at 4:49
paulsm4paulsm4
78k9100126
78k9100126
Nice example but I think thefree
s are missing.
– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try thismat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!
– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
Yes. The way C works, a 2-d array likea
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.
– paulsm4
Nov 19 '18 at 17:58
|
show 2 more comments
Nice example but I think thefree
s are missing.
– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try thismat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!
– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
Yes. The way C works, a 2-d array likea
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.
– paulsm4
Nov 19 '18 at 17:58
Nice example but I think the
free
s are missing.– Osiris
Nov 18 '18 at 5:03
Nice example but I think the
free
s are missing.– Osiris
Nov 18 '18 at 5:03
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
I get an error when I try to run your code, it says a value of type "void *" cannot be assigned to an entity of type "double *" this occurs on line 60
– KolacheMaster
Nov 19 '18 at 16:37
1
1
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try this
mat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!– paulsm4
Nov 19 '18 at 17:04
Sorry - it compiled and ran fine for me (GCC, Ubuntu Bionic Beaver). Please try this
mat[i] = (double *)malloc(sizeof(double)*ncols);
"stdlib.h" should be the correct header for "malloc()". The source file suffix should be ".c" (to ensure compiling as "C", not C++). 'Hope that helps!– paulsm4
Nov 19 '18 at 17:04
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
Awesome! Quick question though, where you are allocating memory for the matrix, why are the rows done with double ** and the columns double *? does doing a double pointer evaluate the matrix in a particular space?
– KolacheMaster
Nov 19 '18 at 17:41
1
1
Yes. The way C works, a 2-d array like
a
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.– paulsm4
Nov 19 '18 at 17:58
Yes. The way C works, a 2-d array like
a
is equivalent to an array of pointers. Hence the need to malloc both 1) the 2-D array, as well as 2) each row in the array.– paulsm4
Nov 19 '18 at 17:58
|
show 2 more comments
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%2f53357358%2fread-in-the-contents-of-a-tab-delimited-text-file-and-save-into-a-single-array-i%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
You know you can't store an entire matrix in a single
double
variable?– Osiris
Nov 18 '18 at 2:27
1
strtok()
andstrtod()
are your friends.– Shawn
Nov 18 '18 at 2:32
1
Over-complicated, and it won't work anyway :( I just wanted to make sure the indentation was correct ;) SUGGESTION: 1) Read about strtok(), 2) Open the file and read a line at a time in a simple loop (like you're doing now), 3) Simply parse the items in the line with strtok, and read them into your array. 4) Close the file when done. 5) Remember - you'll also need a loop to print the array (you can't just do it with a simple "printf()"). Forget about strdup(), forget about ftell()/rewind(), etc - you can eliminate 2/3 of your code :)
– paulsm4
Nov 18 '18 at 2:34
1
There are a number of ways to do it. Read a line at a time with
fgets
and then usestrtod
(utilizing the*endptr
parameter) and scanning forward with either a simple loop orstrchr
to the next','
(or separator char), add1
to the pointer, and repeat. Alternatively tokenize the line withstrtok
with",n"
as your delimiters callingstrtod
on the return fromstrtok
within a loop. (you can also usesscanf
with the%n
specifier to update an offset to do the same thing.) Post a copy of the first 3 or so lines of your data file.– David C. Rankin
Nov 18 '18 at 2:43
1
size = ftell(f);
reports the file length.while(fgets(buff,size - 1,f) != NULL)
only reads a line.– chux
Nov 18 '18 at 3:53