Reputation: 41
I am trying to take the input of the following type:
5 4
a a a a
a b a p
c d e a
d b c a
d h i k
Using the following code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m, n;
scanf("%d %d", &m, &n);
char mat[m][n], str[2 * n];
for (int i = 0; i < m; i++)
{
fgets(str, 2 * n, stdin);
//char d;
//getc(d); // added to absorb if any char remains in stream after pressing enter
int j = 0;
while (j < n)
{
mat[i][j] = str[2 * j];
j++;
}
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("%c ", mat[i][j]);
printf("\n");
}
return 0;
}
The program doesn't take the second line of input as when I press enter after it just prints the output and exists. When I run using GDB it shows Invalid Parameter passed to C runtime function
. I have tried searching it and tried by adding getc after fgets but no success. I am unable to debugg the program.
Please help me. It would be nice if we can make a generic program for the following type of input.
5 4
a ar a alp
atg bk a p
cf dg er alphs
a g hdb gdb
klat cmat s fun
Thanks in advance.
Upvotes: 2
Views: 474
Reputation: 3260
Use getline to read a line. gets
is deprecated after c11.
@Some programmer dude: Actually, getline is not a standard C function, it's a POSIX (Linux, macOS, etc.) function. Which means it's not available for Windows.
See this post to understand difference of gets and getline.
cin.getline()
reads input up to '\n' and stops
cin.gets()
reads input up to '\n' and keeps '\n' in the stream
If you debug your program you can see gets called in each 2 loops:
5 4
=======i is 0
=======i is 1
a a a a
=======i is 2
=======i is 3
a b a p
=======i is 4
So program works but you need discard \n
(and/or \r
).
Also use gets
as you said to surpass first \n
.
So your code can be as
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m, n, len;
scanf("%d %d", &m, &n);
char mat[m][n], str[2*n];
fgets(str, 2 * n, stdin);
for (int i = 0; i < m; i++)
{
printf("=======i is %d\n", i);
//fgets(str, 2 * n, stdin);
getline(&str, &len, stdin);
int j = 0;
while (j < n)
{
mat[i][j] = str[2 * j];
j++;
}
}
printf("=======OUTPUT======");
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("%c ", mat[i][j]);
printf("\n");
}
return 0;
}
output will be as :
4 5
=======i is 0
s s s s
=======i is 1
d d d d
=======i is 2
f f f f
=======i is 3
g g g g
Upvotes: 0
Reputation: 175
As pointed out by @Someprogrammerdude, your code leaves '\n'
in the input stream, and when you enter the for
loop, it first takes '\n'
from the stream and then takes the other input. So, your code breaks before taking the last line of the input.
One of the possible solutions could be:
Since you know how to use fgets()
, I think you should use fgets()
to get the first line too. Then use strtok() to retrieve integers from the string using strtol(). However, this is not a memory-efficient and time-efficient solution.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int m,n;
char *str = (char*)malloc(23*sizeof(char));
//23 = 2*10+1+2, here 10 is the maximum length of two integers,
// 1 is for space and 2 chars to accommodate '\n' and NULL.
fgets(str, 23, stdin);
char *tk = strtok(str, " ");
m = (int)strtol(tk, (char **)NULL, 10);
tk = strtok(NULL, " ");
n = (int) strtol(tk, (char **)NULL, 10);
str = (char *)realloc(str, (2*n+1)*sizeof(char));
char mat[m][n];
/*
Your code
*/
return 0;
}
Upvotes: 1