Reputation: 17
I have to read an undefined matrix from a text file in C language, and i want to read it line by line so that each line will be an integer array.But how do i know where is the end of a line, since i can't use "\n" as in for characters? Here is the code:
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
using namespace System;
typedef struct
{
int *v;
int n;
}vector;
int main(array<System::String ^> ^args)
{
vector *a;
FILE* f;
int n = 15;
int i = 0;
int j,k;
if ((f = fopen("C:\\Users\\Mirelaa\\Documents\\visual studio 2013\\Projects\\MatriceNedefinita\\MatriceNedefinita\\Debug\\fisier2.in", "rt")) == NULL)
{
printf("Fisierul nu poate fi deschis!");
exit(1);
};
a = (vector *)malloc(n * sizeof(vector));
while (!feof(f))
{
a[i].v = (int*)malloc(n * sizeof(int));
a[i].n = 0;
//citeste rand
//citesti fiecare element din rand
j = 0;
while (a[i].v[j] != '\0')// wrong!!
{
fscanf(f, "%d", &a[i].v[j]);
j++;
a[i].n = a[i].n + 1;
}
for (k = 0 ; k < a[i].n ; k++)
{
printf("%d", a[i].v[j]);
printf("\n");
}
i++;
if (i == n)
{
n = 2 * n;
a = (vector *)realloc(a, n * sizeof(vector));
a[i].v = (int *)realloc(a[i].v, n * sizeof(int));
}
}
return 0;
}
Upvotes: 0
Views: 297
Reputation: 154315
Reading a line of integers and saving in a variable sized array is one approach.
The trouble with fscanf(f, "%d",...
is that it first reads white-space and code loses the occurrence of '\n'
. Code needs to look for it by some other means.
But rather than pack all the code in main()
, consider helper functions. Following C function reads one line of numbers and return NULL
on 1) out-of-memory, 2) no data or conversion failure with no numbers read. Otherwise return vector
. It is not limited to any line length.
typedef struct {
int *v;
size_t n;
} vector;
vector *Read_vector(vector *v1, FILE *inf) {
v1->v = NULL;
v1->n = 0;
size_t size = 0;
for (;;) {
int number;
int ch;
// Check leading white-space for \n
while (isspace(ch = fgetc(inf))) {
if (ch == '\n') break;
}
if (ch == '\n' || ch == EOF) break;
ungetc(ch, inf);
if (1 != fscanf(inf, "%d", &number)) {
break;
}
// Is `v1` large enough?
if (v1.n >= size) {
size = size*2 + 1;
vector nu;
nu.v = realloc(v1->v, size * sizeof *nu.v);
if (nu.v == NULL) {
free(v1->v);
v1->v = NULL;
v1->n = 0;
return NULL;
}
v1->v = nu.v;
}
v1.v[v1.n++] = number;
}
if (v1->n == 0) {
return NULL;
}
return v1;
}
With repeated calls, an array of vectors could be had. Leave that to OP as it is very similar to the above.
Note: avoid use while (!feof(f))
.
Upvotes: 1
Reputation: 1313
I would read in a lines with fgets...(see e.g. here)
char *fgets(char *str, int n, FILE *stream)
you can read a line up to $n$ characters line into a string.
This method gives you a way of loading each line individually to a string.
Edit after good comment
It is easier to split up the string with strtok and then use atoi to convert each bit of the string to an integer (rather than use sscanf as in my original answer).
Upvotes: 0