Read from txt file and input to an array in C - c

I have my txt file
4
110
220
112
335
4 is the number of lines and 4*3 the number of int. I have to read "4" then read the remaining and input them into an array
This is what I have
void main(){
int a,n;
int i=0,j=0,k[30]; //
int *N;
FILE *fp = fopen("test.txt", "r");
if(fscanf(fp, "%d", &a) != 1) { //
// something's wrong
}
n=3*a; //3*a numbers in the file
N = malloc(3 * a * sizeof(int));
for(i = 0; i <n;++i) {
int result=fscanf(fp, "%d", &N[i] );
}
fclose(fp);
for(j=0;j<3*a;j++){
k[j]=N[j];
}
printf("%d",k[0]);
}
When I print k[0] it was supposed to print "1" but instead the whole line "110" is printed
Is there any other way to do this???

The format specifier %d does not specify a length, so fscanf will read as many digits as it can; this is why you get 110 instead of just 1.
If you specify a length, like %1d, it will only read as many digits as you tell it to:
for(i = 0; i <n;++i) {
int result=fscanf(fp, "%1d", &N[i] );
}

When you use fscanf with %d format parameter, it retrieves an integer type from the file. Since 110 and the others are all integers, it will directly fetch 110 from file.
So you can either use fscanf with %d parameters in a loop which iterates for a times, or if you want to get it character by character, you can use fscanf with %c parameter but it needs much more effort. So, you should use fscanf with %d parameter and fetch all digits from it by a loop for every number.

The fscanf(fp, "%d", &N[i] ) will catch a number and not a digit. So
fscanf(fp, "%d", &N[0] ) //will catch 110
fscanf(fp, "%d", &N[1] ) //will catch 220
...
If you want to catch digits in your array you have to use the following code:
for(i = 0; i <n;++i) {
int result=fscanf(fp, "%c", &N[i] );
if (isdigit (N[i])) N[i]-='0';
else i--;
}

Related

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;
}

Reading unsigned char from .txt file using fread give different values

I have the following code snipped to read 16 unsigned char values from a .txt file.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j, k, load_size;
unsigned char *buf;
load_size = 16;
buf = (unsigned char *)malloc(load_size);
FILE *fin;
fin = fopen("demo_input1.txt", "r");
fread(buf, 1, load_size, fin);
for(i=0;i<16;i++){
printf("%d ", *buf);
buf++;
}
system("PAUSE");
}
The file 'demo_input1.txt' contains the values 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16. But I am getting output in the console values 49 32 50 32 51 32 52 32 53 32 54 32 55 32 56 32. Can anybody help me by telling me what is going wrong here? Thanks
fread is for reading raw inputs. As your file is formatted text, use the following:
int nums[SIZE];
int count = 0;
while( fscanf(fin, "%d", nums + count) == 1 ) {
if(++count == SIZE) break; /* More than expected numbers in file */
}
Later you can print using:
for(i = 0; i < count; i++) {
printf("%d ", nums[i]);
}
fscanf is one way to read formatted input from files. You can use malloc, walking pointers as shown in your original code snippet or as per your requirements.
What is going on is completly correct, yet not what you expected. So, whats going on? You read 1 byte from the file, into a char, then you output it using %d, which will output as decimal. Have a look at an ascii table, if you read the char 1, its ASCII value is 49, 32 is space, 50 is 2, and so on. You cannot just read plain numbers like that, your code, replacing the %d with %c would only work on binary files, but not on human readable files.
What you want to use instead of fread is fscanf, which works like scanf but reads from a file. There you can specify to read an integer, thus getting the whole numbers without the spaces. These you can check if they are smaller than 256, if yes, cast to char.
The other way of how this can be done is using fgets() to read the whole line to the buffer break the line using space as delimiter and later convert string to integers and store them or print them.
char buf[300];
int a[30],i=0;
while(fgets(buf,sizeof(buf),fin))
{
char *p = strtok(buf," ");
i = 0;
while( p != NULL)
{
a[i] = atoi(p);
printf("%d ",a[i]);
i++;
p = strtok(NULL," ");
}
}
PS: When fgets() is used you need to have predefined large array to hold your input else it may lead to erroneous results.
It is considering the ascii value of space as 32(ASCII for space).
Just make one simple change in the for loop.
Instead of %d use %c
for(i=0;i<16;i++)
{
printf("%c ", *buf);
buf++;
}

C- Reading from a file and getting unexpected results when printing contents of it

I have a program that reads a file from command line (file that consists of integers - see below), puts it into an array and then prints the array.
#include <stdio.h>
#include <stdlib.h>
#define SIZEBUFF 1024
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf("Missing file\n");
return (EXIT_FAILURE);
}
FILE *file = fopen (argv[1],"r");
int integers [144]; //Array that input is stored
char buffer[SIZEBUFF];
int count = 0;
while (fgets(buffer,sizeof (buffer),file) > 0){ // !=EOF gives seg. fault if used
integers[count] = atoi(buffer);
count++;
}
fclose(file);
printf ("The contents of integer array are: \n");
int j;
for (j = 0; j < 144;j++) printf ("%d\t",integers[j]);
return (EXIT_SUCCESS);
}
NOTE: Real file consists of 144 integers. I just took the first 12
How can I print just the numbers that exist in the file?
This problem is because you wrote code assuming that fgets() reads a single integer from file on each call. But its not so if the integers are stored on same line.
fgets() stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first.
So here fgets is reading more than one integer at a time from file so atoi() is not getting the integers in file too.
you can use fscanf() to read the integers directly,
fscanf(file,"%d",&integers[count]);
you can loop through this statement 144 times since you know the number of integers in the file or can use,
fscanf (file, "%d", &integers[count]);
while (!feof (file))
{
fscanf (file, "%d", &integers[++count]);
}
You could use fscanf just as you would use scanf to read 144 integers from the console.
You should use fscanf to read integers from the file into the array.
int count = 0;
while(fscanf(file, "%d", &integers[count++]) == 1)
; // the null statement
int j;
for(j = 0; j < count; j++)
printf("%d\t", integers[j]);

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