Reading from .Txt File into Two Dimensional Array in C++

Reading from .txt file into two dimensional array in c++

I believe that

istream inputStream;
int myArray[3][5];
for(int i = 0; i < 3; i++)
for(int j = 0; j < 5; j++)
istream >> myArray[i][j];

should do what you need.

Reading in a text file into a 2D array in C

Newline character, as the name implies, are characters also. You should have found it suspicious that your output preserves newlines.

There are in fact 13 characters in each line of the file (assuming a unix system). The twelve printable ones, and a newline.

So for i = 1...7 the first character in each "row" is a newline.

Fortunately, scanf can be instructed to skip whitespace characters when awaiting a character input. Simply add a space in the beginning of the format specifier string:

fscanf(fp, " %c", &points[i][j]);

Read 2d array from txt file in c++

There are a lot of other ways to perform the specific task, but i guess your method is not wrong, and you have just made a simple typing mistake in your second for loop condition. so ill just fix your code for you.
and also you could just input single values at a time as u go.

#include<bits/stdc++.h>
using namespace std;
int main()
{
char arr1[10][10];
cout <<"Reading Start" <<endl;
ifstream rfile("test.txt");
int i,j;
for(i=0;i<6;i++){
for(j=0;j<6;j++){
rfile >> arr1[i][j];
cout << arr1[i][j] << " ";
}
cout << endl;
}

cout <<"\nRead Done" <<endl<<endl;
rfile.close();
}

Output : Sample Image

Reading txt file into 2d array C++

The following should work provided the text file is as described and there are any unexpected characters. It is similar to your code except it checks for an unexpected end-of-file (i.e. if there aren't WIDTH rows in the file) within the for loop.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;

int main() {

const int WIDTH = 31;//declaring days or columns for array
const int HEIGHT = 3;//declaring information day and high and low

/* Code to read in txt file */
ifstream infile;
infile.open("weather.txt");

if (!infile) {
cerr << "Unable to open file\n" << endl;
exit(1); // call system to stop
}
/* end code read text file */

int tempDay[HEIGHT][WIDTH];

for (int i = 0; i < WIDTH; ++i) {
for (int j = 0; j < HEIGHT ; ++j) {
if (!(infile >> tempDay[j][i])) {
cerr << "Unexpected end of file\n" << endl;
exit(1); // call system to stop
}
cout << "Location: " << j <<" : " << i << " Data in textFile: " << tempDay[j][i] << endl;
}
}

infile.close();
return 0;
}

How to read data from file into two dimension array in C?

You should change the following line:

int *dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

as follows:

float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

Alternatively, you can declare the array as double and read using %lf

I also had to skip the commas as follows:

#include <stdio.h>
#include <stdlib.h>
#define NUMBEROFINPUT 100 //100 inputs.
#define NUMBEROFCOLUMN 10 //10 rows.

int main(){
float dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

FILE *dataFileptr;
dataFileptr = fopen("group5_8.txt", "r");
if (dataFileptr == NULL){
perror("Error");
return 1;
}

for(int i = 0; i < NUMBEROFINPUT; ++i){
for(int j = 0; j < NUMBEROFCOLUMN; ++j){
fscanf(dataFileptr, "%f", &dataFileInput[i][j]);
fgetc(dataFileptr);
printf("a[%d][%d] = %.2f\n", i+1,j+1, dataFileInput[i][j]);
}
}

fclose(dataFileptr);
}

Note the call to fgetc.

For the sake of completion, I would like you to note that the reading is successful even when using an int* array. The printing fails because the data is interpreted as an int* and then converted to a float. To interpret the bytes stored in the int* array element, first cast the address of the element to a pointer to float, then get the value of the float stored at this address. Same code except for the print statement.

#include <stdio.h>
#include <stdlib.h>
#define NUMBEROFINPUT 100 //100 inputs.
#define NUMBEROFCOLUMN 10 //10 rows.

int main(){
int *dataFileInput[NUMBEROFINPUT][NUMBEROFCOLUMN];

FILE *dataFileptr;
dataFileptr = fopen("group5_8.txt", "r");
if (dataFileptr == NULL){
perror("Error");
return 1;
}

for(int i = 0; i < NUMBEROFINPUT; ++i){
for(int j = 0; j < NUMBEROFCOLUMN; ++j){
fscanf(dataFileptr, "%f", &dataFileInput[i][j]);
fgetc(dataFileptr);
printf("a[%d][%d] = %.2f\n", i+1,j+1, *((float *) &dataFileInput[i][j]));
}
}

fclose(dataFileptr);
}

Read text file into 2D array

int suduku[9][9];

for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
char c;
if (fscanf(file1, " %c", &c) != 1)
…report read failure and exit…
else if (isdigit((unsigned char)c))
sudoku[i][j] = c - '0';
else
sudoku[i][j] = 0;
}
}

Read the character into a character, then convert to an appropriate integer. Note that the code won't care if each character from the matrix is separated from the next by a dozen blank lines and there are 20 spaces before the character, or if the whole input is 81 characters on a single line, or any other variation. As long as there are at least 81 non-white space characters in the file, it'll be OK.

Making a 2d array from a text file

OP wrote this in the comments:

Im so sorry but my teacher clarified everything just now... it turns out that, for each line, the first number is the row, the second the column and the third the element.with the example i have above, 1.2 has to go in the position [0][3]. The matrix does not have to be square.

This makes every thing different. If you don't know the dimensions of the
matrix, then you have to read everything first, then calculate the matrix
dimensions, allocate space for the matrix and then fill it with the values.

I'd do this:

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

#define BLOCK 1024

struct matrix_info {
int col;
int row;
double val;
};

void free_matrix(double **matrix, size_t rows)
{
if(matrix == NULL)
return;

for(size_t i = 0; i < rows; ++i)
free(matrix[i]);
free(matrix);
}

double **readmatrix(const char *fname, size_t *rows, size_t *cols)
{
if(fname == NULL || rows == NULL || cols == NULL)
return NULL;

double **matrix = NULL;
struct matrix_info *info = NULL;
size_t mi_idx = 0; // matrix info index
size_t mi_size = 0;

FILE *fp = fopen(fname, "r");
if(fp == NULL)
{
fprintf(stderr, "Cannot open %s\n", fname);
return NULL;
}

*rows = 0;
*cols = 0;

for(;;)
{
if(mi_idx >= mi_size)
{
struct matrix_info *tmp = realloc(info, (mi_size + BLOCK) * sizeof *info);
if(tmp == NULL)
{
fprintf(stderr, "not enough memory\n");
free(info);
fclose(fp);
return NULL;
}

info = tmp;
mi_size += BLOCK;
}

int ret = fscanf(fp, "%d %d %lf", &info[mi_idx].row, &info[mi_idx].col,
&info[mi_idx].val);

if(ret == EOF)
break; // end of file reached

if(ret != 3)
{
fprintf(stderr, "Error parsing matrix\n");
free(info);
fclose(fp);
return NULL;
}

if(*rows < info[mi_idx].row)
*rows = info[mi_idx].row;

if(*cols < info[mi_idx].col)
*cols = info[mi_idx].col;

mi_idx++;
}

fclose(fp);

// mi_idx is now the length of info
// *cols and *rows have the largest index
// for the matrix, hence the dimension is (rows + 1) x (cols + 1)
(*cols)++;
(*rows)++;

// allocating memory

matrix = calloc(*rows, sizeof *matrix);
if(matrix == NULL)
{
fprintf(stderr, "Not enough memory\n");
free(info);
return NULL;
}

for(size_t i = 0; i < *rows; ++i)
{
matrix[i] = calloc(*cols, sizeof **matrix);
if(matrix[i] == NULL)
{
fprintf(stderr, "Not enough memory\n");
free(info);
free_matrix(matrix, *rows);
return NULL;
}
}

// populating matrix

for(size_t i = 0; i < mi_idx; ++i)
{
int r,c;
r = info[i].row;
c = info[i].col;
matrix[r][c] = info[i].val;
}

free(info);
return matrix;
}

int main(void)
{
const char *fn = "/tmp/matrix.txt";

size_t rows, cols;

double **matrix = readmatrix(fn, &rows, &cols);

if(matrix == NULL)
return 1;

for(size_t i = 0; i < rows; ++i)
{
for(size_t j = 0; j < cols; ++j)
printf("%0.3f ", matrix[i][j]);

puts("");
}

free_matrix(matrix, rows);
return 0;
}

The output is (for a file with your sample data)

5.200 0.000 0.000 1.200 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 3.200
2.100 0.000 0.000 0.000 0.000 4.200
0.000 0.000 0.000 0.000 0.000 2.200

So a quick explanation of what I'm doing:

I read the file and store in an dynamically allocated array the information
about the column, the row and the value. This information is stored in the
struct matrix_info *info.

The idea is that I read every line and extract the three values. While I read
the file, I also store the largest index for the column and the row

    ...

if(*rows < info[mi_idx].row)
*rows = info[mi_idx].row;

if(*cols < info[mi_idx].col)
*cols = info[mi_idx].col;

...

so when the file is read, I know the dimensions of the matrix. Now all values
with their row & column are stored in the info array, so the next step is to
allocate memory for the matrix and fill the values based based on the info[i]
entries.

for(size_t i = 0; i < mi_idx; ++i)
{
int r,c;
r = info[i].row;
c = info[i].col;
matrix[r][c] = info[i].val;
}

At the end I free the memory for info and return the matrix.

Another interesting part is this:

    if(mi_idx >= mi_size)
{
struct matrix_info *tmp = realloc(info, (mi_size + BLOCK) * sizeof *info);
if(tmp == NULL)
{
fprintf(stderr, "not enough memory\n");
free(info);
fclose(fp);
return NULL;
}

info = tmp;
mi_size += BLOCK;
}

Because you mentioned that the only thing you know about the matrix is that it
might contain up to 10000 elements, then the input file might be very big.
Instead of reallocating memory for the info elements on every loop, I allocate
chunks of 1024 (BLOCK) info elements at a time. Thus once a block is full,
the next block is allocated and so on. So I call realloc only every 1024
iterations.

Reading a 2D array from a file in C

I could not resist tweaking and simplifying your code, it was so close, to avoid the use of fgets and use fscanf to read the values directly. Plus basic error checking.

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

#define MWIDTH 100
#define MHEIGHT 100

int main(void){

FILE* f;
int height, width, ii, jj;
float array[MHEIGHT][MWIDTH];

if((f = fopen("plottestdata.txt", "r")) == NULL)
exit(1);

if(fscanf(f, "%d%d", &height, &width) != 2)
exit(1);
if (height < 1 || height > MHEIGHT || width < 1 || width > MWIDTH)
exit(1);

for(jj=0; jj<height; jj++)
for(ii=0; ii<width; ii++)
if(fscanf(f, "%f", &array[jj][ii]) != 1)
exit(1);
fclose(f);

for(jj=0; jj<height; jj++){
for(ii=0; ii<width; ii++)
printf ("%10.1f", array[jj][ii]);
printf("\n");
}
return 0;
}

Program output:

  10.4      15.1      18.5      13.3      20.8
76.5 55.3 94.0 48.5 60.3
2.4 4.6 3.5 4.6 8.9

Read numbers from text file to 2D array

You were well on your way, you just had problems thinking you were reading a character array instead of an array of signed characters (which could be changed to int, etc) Here is your example:

#include <stdio.h>

#define MAXB 32
#define MAXL 18
#define MAXD 3

int main(void)
{
int i = 0;
int numlines = 0;
char buf[MAXB] = {0};
char lines[MAXL][MAXD];

FILE *fp = fopen("inputs/control.txt", "r");

if (fp == 0)
{
fprintf(stderr, "failed to open inputs/control.txt\n");
return 1;
}

while (i < MAXL && fgets (buf, MAXB - 1, fp))
{
if (sscanf (buf, "%hhd %hhd %hhd", &lines[i][0], &lines[i][1], &lines[i][2]) == 3)
i++;
}

fclose(fp);

numlines = i;
int j = 0;

for (i = 0; i < numlines; i++)
for (j = 0; j < MAXD; j++)
printf (" line[%2d][%2d] : %hhd\n", i, j, lines[i][j]);

printf ("\n");

return 0;
}

Output

$ ./bin/read_array_a3
line[ 0][ 0] : 1
line[ 0][ 1] : 0
line[ 0][ 2] : 0
line[ 1][ 0] : 0
line[ 1][ 1] : 0
line[ 1][ 2] : 0
line[ 2][ 0] : 1
line[ 2][ 1] : 0
line[ 2][ 2] : 1
line[ 3][ 0] : 0
line[ 3][ 1] : 0
line[ 3][ 2] : 2
line[ 4][ 0] : 1
line[ 4][ 1] : 0
line[ 4][ 2] : 2

Note: char lines[MAXL][MAXD]; is fine, you just must understand that each element is restricted to an 8-bit signed value, meaning values between -128 < val < 127. You can make them int if you need to store larger values.



Related Topics



Leave a reply



Submit