0

This code says segmentation fault cause the program's scanf isn't working. I used a debugger to find out this. The scanf(num) is skipped. And thus the segmentation fault. Can somebody tell why the scanf is being skipped? I used [^\n] so that scanf can read string with spaces. Help.

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(void)
{
    int a, b;

    scanf("%d %d", &a, &b);
    int sumr, maxr;
    int sumc, maxc;

    int white[b + 1];
    white[0] = -1;
    int ele[b][a];
    for (int opl = 0; opl < a; opl++)
    {
        for (int pl = 0; pl < b; pl++)
        {
            ele[pl][opl] = 0;
        }
    }
    char num[100000];
    int c = -1;
c:
    c++;
    scanf("%[^\n]%*c", num);
    int hu = 0;
    int len = strlen(num);
    white[b] = len;
    for (int ji = 0; ji < len; ji++)
    {
        if (isspace(num[ji]))
        {
            white[hu] = ji;
            hu++;
        }
    }
    for (int ft = 0; ft < b; ft++)

    {
        int lopl = 1;
        for (int koi = white[ft + 1] - 1; koi > white[ft]; koi--)
        {
            ele[ft][c] += lopl * (num[koi] - '0');
            lopl = lopl * 10;
        }
    }

    if (a > c)
        goto c;
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • 1
    One of your problems is that `scanf("%d %d", …)` leaves a newline in the buffer. Your next input is `scanf("%[^\n]%*c", …)` which immediately fails because of the newline left behind. As noted in some of the answers below, you don't check that your inputs succeed, so your code blunders on using an uninitialized variable, which generally leads to unhappiness. – Jonathan Leffler Jan 15 '21 at 05:01

2 Answers2

2
scanf("%[^\n]%*c", num);

As a first step. you should always check the return value of functions that can adveresely affect your program. In other words, something like:

if (scanf("%d %d", &a, &b) != 2) { handleOneProblem(); }
if (scanf("%[^\n]%*c", num) < 1) { handleAnother(); }

If that second one fails, then num will be left containing whatever arbitrary data it contained before the call, and you probably don't want to then use it as if it contains a valid string.

On top of that, you should be aware that some, but not all, scanf format specifiers will gobble up white space before attempting to read the data. For example, %d will first skip over whitespace and then attempt to read an integer. However, format specifiers such as [ and c will not.

And none of them will gobble up whitespace after the field has been read for the format specifier. That means, if you want that done, you need to do it yourself, with a set of functions like:

#include <stdio.h>

int gobbleLineFile(FILE *inFile) {
    int ch;
    while ((ch = fgetc(inFile)) != '\n' && ch != EOF) {}
    return ch;
}

int gobbleLineStdIn(void) { return gobbleLineFile(stdin); }

As an aside, a lot of problems with scanf are caused by mixing those format specifiers that skip white-space, with those that don't. You can code around that as per above suggestion but, if you're expecting the user to give line-based input, it's often better to do everything as line-based, then use sscanf to break apart the lines.

A fairly decent line-based input routine can be found here.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

You have to catch the '\n' that was left from the first scanf.

Either change it to: scanf("%d %d\n", &a, &b);

or put a getchar(); right after it.

Because the next reading: scanf("%[^\n]%*c", num); will read until the next '\n', which is the first thing left on the buffer.

vmp
  • 2,370
  • 1
  • 13
  • 17
  • 1
    I wouldn't use `getchar()`, that will only get *one* whitespace, which will be problematic if user enters `12`. – paxdiablo Jan 15 '21 at 05:00
  • Use a 'gobble' function — maybe an inline function — such as: `static inline void gobble(void) { int c; while ((c = getchar()) != EOF && c != '\n') ; }`. This eats up all the leftover characters until the next newline. – Jonathan Leffler Jan 15 '21 at 05:03
  • 1
    @JonathanLeffler: That could be the best function name EVER! Using a similar one to expand on my answer, hope you don't mind :-) – paxdiablo Jan 15 '21 at 07:56