user17762868
user17762868

Reputation: 41

Invalid Parameter passed to C runtime function in C

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

Answers (2)

Majid Hajibaba
Majid Hajibaba

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

Kumar
Kumar

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

Related Questions