input text file into an 2d array in c - c

#include<stdlib.h>
#include<stdio.h>
int main() {
FILE* file = fopen ("fourth.txt", "r");
int i = 0;
int rows=0;
int rows2=0;
int columns=0;
int counter=0;
int length=0;
int multiply=0;
fscanf (file, "%d", &i);
rows=i;
printf("the rows are %d\n", i);
int matrix[rows][rows];
length=rows*rows;
if (rows<=0) {
printf("error, this file cannot be processed");
return 0;
}
do
{
if (fscanf(file, "%d", &i)==1) {
if (counter<length) {
matrix[rows2][columns]=i;
counter++;
columns++;
if (columns==rows) {
rows2++;
columns=0;
}
}
multiply=i;
}
} while (!feof(file));
fclose (file);
for ( int c = 0; c < rows; c++ ) {
for ( int j = 0; j < rows; j++ ) {
printf("matrix[%d][%d] = %d\n", c,j, matrix[c][j] );
}
}
printf("the multiply is %d", multiply);
I am trying to create a matrix exponential (matrix multiplication in another words). However before I perform the actual mathematical process, I have to read numbers as input from a txt file and store them in a 2d array. Above is what I have from the code so far, however, I am struggling to actually input the numbers into the array because when I was testing my 2d array out at the very end, I was getting odd results.
for example:
1. Inputs:
3
123
456
789
2
The 3 represents the number of rows, which is the same as the number of columns for this particular 2d array because the matrix is square, meaning
all rows and columns are the same.
The 2 represents the exponent, which is the number of times I have to multiply the original matrix by itself.
However my output is
matrix[0][0] = 123
matrix[0][1] = 456,
matrix[0][2] = 789
matrix[1][0] = 2
matrix[1][1] = 4214800
matrix[1][2] = 0
matrix[2][0] = 3
matrix[2][1] = 0
matrix[2][2] = 0
Expected output has to be:
123
456
789
in a 2d array
Is there a reason why?
Also how would I modify the code so no matter what the input is in the txt file regarding different rows and columns, I could still format the proper 2d array. Thanks

In your input text file, the digits in a line are not separated in any way. If you need multi-digit numbers, consider separating them by a symbol like space or semicolon.
If the matrix has only single digit whole numbers (ie, numbers from 0 to 9), it would be fine.
But if there the 3 numbers in a line are, say, 21, 13 and 4, in the input file it would be just 21134.
There's no way to find if it was 211,3,4 or 21,1,34 or 2,113,4 or .......
With the fscanf() in your program, each %d will read the entire line considering it to be a single number and assign it to the variable i.
Instead of reading the size first into i and then copying it to rows like
fscanf (file, "%d", &i);
rows=i;
you could directly read into rows
fscanf( file, "%d", &rows);
And read the values like
for(rows2=0; rows2<rows; ++rows2)
{
if( fscanf(file, "%1d%1d%1d", &matrix[rows2][0], &matrix[rows2][1], &matrix[rows2][2]) != 3)
{
perror("Error");
break;
}
}
Then read the value for multiply at the end like
fscanf(file, "%d", &multiply);
You may check the return value of fscanf() to check if any error occurred.
You used !feof(file) to check end of file. I don't know much but have a look here.

Related

In C is their anyway way to read the contents of a file, line-by-line, and store each integer value (preline) into a array separately?

My C Code is as so:
#include <stdio.h>
int main( int argc, char ** argv){
FILE *myFile;
myFile = fopen("numbers.txt", "r");
//read file into array
int numberArray[16];
for (int i = 0; i < 16; i++){
fscanf(myFile, "%1d", &numberArray[i]);
}
for (int i = 0; i < 16; i++){
printf("Number is: %d\n", numberArray[i]);
}
}
My numbers.txt file contains the follow values:
5
6
70
80
50
43
But for some reason my output
Number is: 5
Number is: 6
Number is: 7
Number is: 0
Number is: 8
Number is: 0
Number is: 5
Number is: 0
Number is: 4
Number is: 3
Number is: 0
Number is: 0
Number is: 4195904
Number is: 0
Number is: 4195520
Number is: 0
However I'm expecting it to print out numberArray to print out the identical contents of the text file. I'm not exactly sure why it's doing this, does anyone happen to know the reason? I'm aware that I'm making an array bigger than the amount of values that I can store, but I'm still confused as to why it can't store 70, 80, etc into one index?
It is because you are reading only 1 digit at a time.
Hence change the below.
fscanf(myFile, "%1d", &numberArray[i]);
to
fscanf(myFile, "%d", &numberArray[i]);
And your array should be of size number of integers in the file.
int numberArray[6];
for (int i = 0; i < 6; i++)
or
while (fscanf(myFile, "%d", &numberArray[i++]) == 1);
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *myFile = fopen("numbers.txt", "r"); // just init your variable directly
if (!myFile) { // Always check if there is no error
return EXIT_FAILURE; // handle it as you like
}
#define SIZE 16 // Avoid magic number
int numberArray[SIZE];
size_t n = 0; // n will represent the size of valid values inside the array
// Always check if scanf family has parsed your input also "%1d" ask to only parse
// one digit, so use %d if you want parse an integer
while (n < SIZE && fscanf(myFile, "%d", numberArray + n) == 1) {
n++;
}
for (size_t i = 0; i < n; i++) {
printf("Number is: %d\n", numberArray[i]);
}
}

Reading Rows and Columns from File in C

I am trying to read this input txt file with my C code:
4 3
1.4 4.6 1
1.6 6.65 1
7.8 1.45 0
7 -2 2
and separate them into rows and columns so that I can sort. I tried doing that but I kept getting weird numbers.
So I tried printing out the rows and columns after I read them from the file and the output was zero. I realized then that my code is not reading the numbers from my text file properly. I have tried different means to fix to no avail. Any help or pointers will be highly appreciated.
#include <stdio.h>
#include <string.h>
#include <stdbool.h> //for bool
int main(){
setvbuf(stdout, NULL,_IONBF, 0);
int c;
FILE *file;
FILE *infile;
char filename[99];
char choice;
int rows, columns;
//while(choice == 'y' || choice == 'Y'){
printf("%s", "Enter file name: ");
fgets(filename, 99, stdin);
char *p = strchr(filename, '\n'); // p will point to the newline in filename
if(p) *p = 0;
file = fopen(filename, "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
else{
puts("FILE NOT FOUND");
}
//read rows and columns from file
printf("%s","\n");
fscanf(file, "%d", &rows);
fscanf(file, "%d", &columns);
printf("%d", rows);
printf("%d", columns);
}
Problem 1
int rows = 0;
int columns = 0;
float matrix[rows][columns];
float sumOfRows[rows];
is not right.
After that, the number of elements in matrix and sumOfRows is fixed. They won't change if you change the values of rows and columns later in your program.
You need to read the values of rows and columns first before you define matrix and sumOfRows.
Problem 2
fscanf(file, "%d", &matrix[rows][columns]);
printf("%f",matrix[rows][columns]);
are not right either. Given the defition of matrix, use of matrix[rows][columns] is not right. They access the array using out of bounds indices.
Remember that given an array of size N, the valid indices are 0 to N-1.
Here's one way to proceed to resolve your problems:
fscanf(file, "%d", &rows); // Use %d, not %f
fscanf(file, "%d", &columns); // Use %d, not %f
// Now define the arrays.
float matrix[rows][columns];
float sumOfRows[rows];
// Read the data of matrix
for (int i = 0; i < rows; ++i )
{
for (int j = 0; j < columns; ++j )
{
fscanf(file, "%f", &matrix[i][j]); // Use %f, not %d
}
}
Your problem (actually, two problems) are in the if (file) {... block. First, you use a loop to read all characters from the file. Because of that, at the end of the loop you are also at the end of the file. Any further calls to fscanf result in undefined behavior.
Second, if the file did not open, you print a message (to the wrong output) and still continue to the fscanf part, which definitely leads to undefined behavior.
Solution: Remove the while loop and fix the error handling code:
if(file) {
// Nothing!
} else {
perror(filename);
return 1; // or return EXIT_FAILURE;
}

read a file and save as a matrix

i have a file like that :
1 100
2 200
3 300
4 400
1
i want to save it as a matrix and i want to save NULL if there is no second number !
i tried to write the program but it does not work correctly !
#include<stdio.h>
int main() {
int k=0 ,i,j , arr[100][100];
FILE *in= fopen("file.txt","r");
char line[1000];
while(fgets(line,1000,in) !=NULL) k++;
fgets(line,1000,in);
for (i=0;i<k;i++){
for (j=0;j<2;j++){
int tmp ;
fscanf(in ,"%d", &tmp) ;
arr[i][j] = tmp ;
}
}
fclose(in);
return 0; }
Two major problems:
The first is that the first loop will read all lines, even the one with the single number on the line. That means the lonely fgets call will not do anything, and more importantly that the value of k will be wrong.
The second problem is that once you read all data from the file, you don't go back to the beginning of the file, instead you continue to try and read from beyond the end of the file.
The first problem can be solve by skipping the second fgets call, and decreasing k by one.
The second problem can be solved by calling rewind after you counted the number of lines.
Also when you actually read the numbers, you don't need the inner loop, just do e.g.
scanf("%d %d", &arr[i][0], &arr[i][1]);
Actually, you don't need the first line-counting loop at all, you can do it all in a single loop, by using fgets and sscanf and then checking the return value of sscanf. So your program could look something like
#include <stdio.h>
int main(void)
{
int values[100][2];
FILE *input = fopen("file.txt", "r");
size_t entries = 0;
if (input != NULL)
{
char buffer[40];
while (fgets(buffer, sizeof(buffer), input) != NULL && entries < 100)
{
int res = sscanf(buffer, "%d %d", &values[entries][0], &values[entries][1]);
if (res <= 1 || res == EOF)
{
// Read the last line with only one number, or an error happened
values[entries][0] = 0;
values[entries][1] = 0;
break;
}
++entries;
}
if (ferror(input))
{
printf("Error reading file\n");
}
fclose(input);
}
// All done, the number of "records" or "entries" is in the variable entries
// Example code: print the values
for (size_t i = 0; i < entries; ++i)
printf("Line %d: %d %d\n", i + 1, values[i][0], values[i][1]);
return 0;
}

C Reading numbers from file and placing them in range bins and printing to file

I'm having an issue with this program.
What I'm trying to do is read lines from the file input.txt, where the first line is the number of integers in the file. input.txt is formatted
5 //num of ints
2
40
49
90
70
Then, I want to print to file output.txt so that output.txt is basically.
range 0-9 1
range 10-19 0
range 20-29 0
range 30-39 0
range 40-49 2
range 50-59 0
range 60-69 0
range 70-79 1
range 80-89 0
range 90-99 1
The ranges will only go up to 99. Thus there is only 10 ranges. So there will never be a number over 99 after the initial line in input.txt.
The issue I'm having is that the program works fine as long as the number of guesses is 10. I know this has to do with how I set the range numbers to increase, since it's tied to the loop. I'm lost on how to do it properly.
Any advice? Thanks, in advance!
What I've got so far:
/*
Print a numbers in range to file output.txt from the list of numbers in file input.txt
*/
#include <stdio.h>
int main(void)
{
FILE *input;
FILE *output;
int num_guesses, nums, bin_count=0, guesses_in_bin;
int i, j, k, firstline;
int Bin_Start = 0;
int bin[10];
input= fopen("input.txt", "r");
output= fopen("output.txt", "w");
fprintf(output, "Values Amounts\n");
fscanf(input, "%d", &num_guesses); //scans first line of input.txt for the number of guesses
for (j=0; j< (num_guesses); j++) //for number of guesses run inside loop
{
for (i=0; i< (num_guesses); i++)
{
fscanf(input, "%d", &nums);
//printf(" %d\n", nums);
if (nums >= Bin_Start && nums <= Bin_Start+9) //checks if number belongs in bin.
bin_count = bin_count+1;
}
//rewind
rewind(input);
fscanf(input, "%d", &firstline); // used to ignore first line of file
//reset bin count
numbers_in_bin = bin_count;
bin_count = 0;
fprintf(output, "%2d - %2d %d", Bin_Start, Bin_Start+9, numbers_in_bin);
fprintf(output, "\n");
//Update to next bin
Bin_Start = Bin_Start+10;
}
fclose(input);
fclose(output);
return 0;
}
Without even looking for more-or-less subtle bugs, stop right here, this solution is already wrong in its concept. The only sane way to solve this is create counters for all ten possible bins in advance like:
int bin[10] = { 0 };
then scan the file one time and do something as simple as
bin[input/10]++;
for output, loop over your bins, eg:
for (int i = 0; i < 10; ++i)
{
printf("%d-%d:\t%d\n", 10*i, 10*i+9, bin[i]);
}

Read from txt file with unknown numbers of int in C

I have to read "N" int from .txt file and place each one to an array X[i]
But the problem is, I'm not suposed to know how many int are in the txt. The code has to work for every txt following this model
5 4
1 2 3
1 3 4
2 3 5
4 5 5
So I have, in the first line, the second number (4 in the exemple) the number of int in the txt will be N=4*3 (4 lines with 3 numbers (ALWAYS second number*3)) + 2 (first line)
The only code I know how to do is when I know how much numbers, like
int t[14] // I know there are 14 numbers on the .txt
while(fgets(buf, sizeof(buf), fp)) {
int result = sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5], &t[6],&t[7],&t[8],&t[9],&t[10], &t[11],&t[12],&t[13]);
if (result <= 0) break; // EOF, IO error, bad data
for (r=0; r<result; r++) {
if (i >= sizeof(X)/sizeof(X[0])) break; // too many
X[i++] = t[r]; //put them in the X[MAX]
}
}
And I need to read every number cause like in
2 3 5
I'll place 5 to a array[2][3]
How I am supposed to do this?
Can someone show me an example???
Thanks!
A simple template:
int a, b, i;
int *N;
if(fscanf(fp, "%d%d", &a, &b) != 2) { /* Read the first 2 integers */
/* Unable to read in 2 integers. Handle error... */
}
N = malloc(3 * b * sizeof(int)); /* Allocate enough space */
for(i = 0; i < 3*b; ++i) {
if(fscanf(fp, "%d", &N[i]) != 1) { /* Read numbers one-by-one */
/* Input may not be enough. Handle error... */
}
}
/* Now you have (3*b) integers stored in N */
/* after operations completed... */
free(N);
There is no need to read in line-by-line and guess how many numbers are there. Just call fscanf() again and again since your input is delimited by space characters and newline characters.

Resources