0

I am solving Problem 'Red Light Green Light' with code 'DOLL' on Code chef.

Code Chef: Red Light Green Light

In this Problem, I need to take N inputs in one line. I tried using scanf() but to no avail, It didn't worked. It was talking N inputs in N line which isn't what I want. I tried using fgets and strtok. But There was some error coming which I am not understanding. So How can I do it?

void main(){
    int T,N,K,sum_N=0;
    int test_arr[N];
    char name;
    char *token;
    scanf("%d",&T);
    if(T<0||T>100000) printf("Wrong Input Cases");  // Condition Checking for T
    if(sum_N>500000) printf("Exceeded Sum");    //Condition Checking for sum of N
    while(T--){
        scanf("%d %d",&N,&K);
        if((N||K)<0||(N||K)>100000) printf("Wrong Values"); //Conditon Checking for N and K
        // Here N Input in one Line are taken
        fgets(name,sizeof(name),stdin);
        token = strtok(name," ");
        for(int i=0;i<N;i++){
            test_arr[i] = *(token+i);
        }

        int ctr=0;
        for(int i=0;i<N;i++){
            if(test_arr[i]>K) ctr++;
        }
        printf("%d",ctr);
    }
}

ERROR

  • 1
    `if((N||K)<0||(N||K)>100000)` is not the way to test constraints. `N||K` is always either `0` or `1`. in any case, they don't give you out of range values - they tell you what to *expect*. – Weather Vane May 08 '22 at 19:43
  • 1
    Don't mix `scanf` with `fgets`. – Zakk May 08 '22 at 19:45
  • 1
    `fgets` takes a buffer of chars, not a single char. I think in this case, it is easier to just scan numbers with `scanf("%d, ...)"`, otherwise you will have to make the line big enough to accomodate 10,000 ints. – M Oehm May 08 '22 at 19:46
  • 2
    There is a lot more wrong with the code. `if(sum_N>500000) printf("Exceeded Sum");` but `sum_N` is always 0. Also `int test_arr[N];` is *undefined behaviour* because `N` has an indeterminate value. Please don't try these problems as a learning tool - they are amusements for practised programmers. If you do, read the problem statement very carefully. Nowhere does it ask for the outputs you have given. And when you do output the answer to each test case there is no newline, unlike the example shown. – Weather Vane May 08 '22 at 19:50
  • By the problem description, you shouldn't need to care about whether numbers are on one line or not -- you always read N before reading N values, so there's no reason to use anything other than scanf. – Chris Dodd May 08 '22 at 21:41
  • @WeatherVane Can you tell from which platform I should practice then? Which platform would I use for learning? – RACHIT MITTAL May 09 '22 at 16:45
  • Please see [The Definitive C Book Guide and List](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). Find on-line tutorial courses with exercises. IMO a good way to practice is with a project. For example simple games like hangman and tic-tac-toe, more complex card games, or advanced games like chess. One problem with the challenge sites is they encourage you to cut corners in the interest of speed, in particular one of the worst sins: not validating user input because it does need to be. In the real world it is essential. – Weather Vane May 09 '22 at 17:00

2 Answers2

1

You need to ask yourself a couple of questions:

  • do you need to check for "invalid" input, and reject cases where the input is split over multiple lines.
  • do you need to read all the numbers on a line of input WITHOUT knowing before hand how many there are supposed to be.

If the answer to both of those is no, there's no reason to check or care about what is on one line vs what is on another. Just use scanf to read numbers and don't worry about spacing or what is on which line.

scanf("%d", &test_cases);   // number of test cases
for (int i = 0; i < test_cases; ++i) {
    scanf("%d%d", &N, &height);  // number of values and boundary height
    int val[N];
    for (j = 0; j < N; ++j)
        scanf("%d", &val[j]);

Note that there are never any spaces or newlines in the scanf format strings. You don't need them, and they might cause confusion. You just read numbers. If you're paranoid, you can check the return value of scanf -- it should always be the number of items read (1, 2, or 1 in the 3 calls above), but if it is not, the only useful thing you can do is print an error message and exit.

If you do need to care about the newlines (most commonly because you don't know how many numbers will be on a line), use fgets + sscanf:

char buffer[MAXLINE];  // buffer big enough for the largest line
int vals[MAXVALS];     // array large enough for the maximum number of vals
char *p = fgets(buffer, sizeof(buffer));    // read a line
int N = 0, len;
while (N < MAXVALS && sscanf(p, "%d%n", &vals[N], &len) == 1) {
    p += len;
    ++N; }
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
1

Change char name; to char name[1024]; or something similar. char name; is not a string but a single character. fgets and strtok is looking for a pointer to a string but getting a character variable.

Gerhard
  • 6,850
  • 8
  • 51
  • 81