There are many ways to read this but I find it always boring.
As the matrix is int
help a little, and I’ll show you a way.
The logic
If you didn’t know how many columns there were until the guy typed the whole line and hit ENTER then you’d have to count the fields and see how many were in the first row.
From there would know how many columns were and in the next rows would be solved.
To count the fields you can read the whole line with fgets()
, the simple because then you don’t have to worry about anything else.
Example
If you read the line with fgets(linha,sizeof(linha),stdin);
that loop
char* p = linha;
char* next = NULL;
unsigned nc = 0;
printf("\n\nLinha: \"%s\"\n", teste[t]);
while ((*p != 0))
{
long numero = strtol(p, &next, 10);
if ((next - p) == 0) break;
p = next;
printf("%ld ", numero);
nc += 1;
} // uma coluna
printf("\nLeu %u campos nessa linha\n", nc);
will read fields 1 to 1 in numero
and count in nc
how many are.
I will leave a more complete example below.
The difference of reading with strtol()
instead of scanf()
is that in the first case the function was written with that in mind: strtol()
can return a pointer to the string indicating how far it was consumed and so you can go through the string without testing the indexes and looking for the spaces and such.
scanf()
and other family functions, such as sscanf()
, on the other hand, they were written to consume tabular data and not "walk" along the line unless you are reading a file. But scanf()
treats space, TAB and newline generic whitespace and you can’t tell if the line ended when reading a field because the function goes straight: everything is whitespace and cannot distinguish the newline
. Only with fscanf()
and when you have a delimiter, like a file csv, if you can use this and read easily, because you can test whether the field ended with the delimiter or with the newline, but that is not the case here: such a delimiter cannot be whitespace: nor TAB
or space. It can be newline
but then your problem would be another :).
An example in C
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "bloco.h"
int main(void)
{
char* teste[] = // uns testes basicos
{
"nada",
"1 2 3 4 5 6 7 8 9 10",
"2147483647 -2147483648",
"21474836472147483648",
""
};
for (int t = 0; teste[t][0] != 0; t += 1)
{ // testa uma "linha" do vetor
char* p = teste[t];
char* next = NULL;
unsigned nc = 0;
printf("Linha: \"%s\"\n", teste[t]);
while ((*p != 0))
{
long numero = strtol(p, &next, 10);
if ((numero == LONG_MAX) || (numero == LONG_MIN))
{
// e se o cara digitou isso mesmo?
if (errno == ERANGE)
{
perror("Erro na entrada");
break;
}
}
if ((next - p) == 0) break;
p = next;
printf("%ld ", numero);
nc += 1;
} // uma coluna
printf("\nLeu %u campos nessa linha\n\n", nc);
}; // for
return 0;
}
The program uses whatever you have in teste
and rotate that loop I showed you.
char* teste[] = // uns testes basicos
{
"nada",
"1 2 3 4 5 6 7 8 9 10",
"2147483647 -2147483648",
"21474836472147483648",
""
};
Every line of teste
is like a line typed by the user and so is faster to test the hypotheses. The program stops when any error occurs (overflow of course, since a int
has limit) or find an empty string, which is there at the end in the example. A common test technique.
the exit
Linha: "nada"
Leu 0 campos nessa linha
Linha: "1 2 3 4 5 6 7 8 9 10"
1 2 3 4 5 6 7 8 9 10
Leu 10 campos nessa linha
Linha: "2147483647 -2147483648"
2147483647 -2147483648
Leu 2 campos nessa linha
Linha: "21474836472147483648"
Erro na entrada: Result too large
Leu 0 campos nessa linha``none
Note that I left a complete error condition test. And the third line has the largest and smallest value possible to read.
The English phrase is from the system saying that error gave in the fourth line because the number is WELL large...
How to put this on your show
How do you know how many columns are can declare an array of int
and go placing the numbers of each line in the vector, using exactly the loop I showed you above.
int colunas = 0;
If the program will read the total of columns just create the array then...
int* linha = (int*) malloc(colunas * sizeof(int));
And you can allocate one for each row or if you know how many you can allocate direct, just by multiplying rows x columns...
I imagine your doubt isn’t in that part and I’ll focus on the topic.
But how many numbers are in total ? How do you know when to stop ?
– Isac
The
scanf
can read more than one value per line, since it does not consume the line break if it does not find it necessary. Then simply call several times in a loop, but it is not yet clear what the criteria for stopping– hkotsubo
at the beginning it will give the amount of columns, so if it is 4 columns it would be 4 numbers
– Nathália
So I suggest [Dit] the question and put all these details in the text. So people don’t need to "hunt" information in the comments. But anyway, if you have the amount, just wear a bow and go reading...
– hkotsubo