Your Existing Issues
- char str[50];is far too short. Up to 20 grades as much as 3-digits each (for- 100) with at least one space between the numbers -- that takes a bare minimum of- 80characters (including the nul-terminating character) PLUS storage for type and at least one additional whitespace. Rule: never SKIMP on buffer size. Users can and will type more than they should. Minimum of 1K buffers unless on embedded systems is recommended.
- for gradeTypeyou need an array ofcharnot an array of pointers-tochar,
- good job using fgets()to read the input,
- there is no need to loop counting spaces, you can simply increment numValuesas you perform your conversions toint,
- an empty brace-initializer is fine in C++, but not C. If you had full warnings enabled you would have learned "warning: ISO C forbids empty initializer braces". (either use a named-initializer or provide a initializer/value for each member),
- to enable warnings, for gccuse-Wall -Wextra -pedantic -Wshadowand consider-Werrorto treat warnings as errors. Since you are attempting to usesscanf_sit is likely you are usingcl.exethe compiler/linker for VS. There enabling/W3is sufficient,
- you can't use any input or conversion function correctly unless you validate the input or conversion succeeded or failed by checking the return,
- for (int i = 0; i <= sizeof(grades.a_Nums); i++)invokes Undefined Behavior attempting to convert- 80values.- sizeof(grades.a_Nums)is, e.g.- 20 inttimes- 4-bytes per intequals- 80. If you do it that way, and presuming your loop counting spaces results in the correct number of values, your loop would be- for (int i = 0; i < grades.numValues; i++).
Comments On Your Approach
While you can use sscanf() if you include the "%n" specifier to capture the number of characters consumed with each conversion, and add that value to the offset for your next call, you should really use strtol() to work through the string of integers converting to int. (that's what it was designed to do).
Further, all sscanf() can do it give you a succeed / fail diagnostic through the return value, leaving you to handle the accumulated offset for each successive call -- and the likelihood of a mistake along the way.
Compare with the prototype for strtol(), e.g.
  long int strtol(const char *nptr, char **endptr, int base);
Where nptr is a pointer to the beginning of the string containing numbers, endptr is the address of a pointer that strtol() will update for you to point 1-past the last digit converted. Think about that for a minute. On your first conversion, the number at the beginning of the string is converted and endptr is updated to 1-past the last digit in that number (already set up for your next call after you assign nptr = endptr;) And since the strtol() conversion ignores leading whitespace, this makes it extremely easy to step down a string converting all space separated integers one after the other.
Moreover, strtol() provides detailed error reporting of exactly what failed where allowing you to recover from minor variations in format.
The base parameter allows a conversion for any base between base-2 and base-36 (providing 0 as the base will automatically handle conversions to base-8, base-10 or base-16 depending on whether the number begins with a 0, no prefix, or 0X or 0x, respectively). Also note the return type is long, so you need to assign to a long and then validate your number is within the range of int.
Minimal Example Using strtol()
Putting the above together, you can write an example with the minimum required validation similar to what follows. Note, there are a large number of additional explanations provided inline in comments within the code, as well as identifying areas where you should provide additional checks or validations.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#define ARRSZ   20        /* if you need a constant, #define one (or more) */
#define BUFSZ 1024        /* don't skimp on buffer size */
typedef struct {          /* a typedef makes using a struct convenient, you */
    int a_Nums[ARRSZ];    /* don't need to type "struct" before gradeData */
    int numValues;
    char gradeType[ARRSZ];  /* array of 20 chars, not pointers, not const */
} gradeData;
/* simple function to print the contents of a gradeData struct */
void prngradeData (gradeData *g)
{
    if (!g->numValues || !*g->gradeType) {    /* no values or empty-string */
        return;
    }
    
    /* output type and prefix for grades */
    printf ("\ntype   : %s\ngrades :", g->gradeType);
    
    for (int i = 0; i < g->numValues; i++) {  /* output grades */
        printf (" %d", g->a_Nums[i]);
    }
    putchar ('\n');     /* tidy up with newline */
}
int main (void) {
    
    gradeData grades = { .a_Nums = {0} };     /* {} initializer is C++ */
    size_t nchars = 0;    /* numer of chars in gradeType */
    char str[BUFSZ],
         *p = str;        /* pointer to str */
    /* no conversions, fputs() is fine (see fputs() / fgets()) */
    fputs ("Enter a student's grade type and grades "
           "(e.g. Quiz 41 20 90 81):\n", stdout);
    /* validate EVERY input, handle Ctrl+d (manual EOF) */
    if (!fgets(str, sizeof str, stdin)) {
        puts ("(user canceled input)");
        return 0;
    }
    nchars = strcspn (str, " \t\n");  /* number of chars to 1st whitespace */
    /* if no chars or too many or space not found, invalid format */
    if (nchars == 1 || nchars >= ARRSZ || str[nchars] == '\n') {
        fputs ("error: invalid input format.\n", stderr);
        return 1;
    }
    memcpy (grades.gradeType, str, nchars);   /* store int gradeType */
    grades.gradeType[nchars] = 0;             /* nul-terminate string */
     
    p += nchars;    /* move pointer one beyond gradeType */
    
    while (grades.numValues < ARRSZ) {      /* loop while array not full */
        char *endptr = NULL;                /* endptr for strtol */
        long tmp = 0;                       /* temp long for conversion */
        
        errno = 0;                          /* reset errno */
        tmp = strtol (p, &endptr, 0);       /* attempt conversion */
        
        /* validate the conversion - minimum 3-conditions */
        if (p == endptr) {  /* check no digits converted */
            fprintf (stderr, "error: no digits converted: %s", p);
            break;
        }
        else if (errno) {   /* check error/overflow in conversion */
            perror ("strtol-grade");
            break;
        }
        else if (tmp < INT_MIN || INT_MAX < tmp) {  /* validate int */
            fputs ("error: conversion exceeds size of int.\n", stderr);
            break;
        }
        
        grades.a_Nums[grades.numValues++] = tmp;    /* assing to array */
        
        p = endptr;       /* update p to 1 past last digit converted */
        
        /* note: can scan forward in string to next +/- or digit,
         * to enhance check for end of string -- that's left to you.
         */
        
        if (!*p || *p == '\n') {  /* check if end of string */
            break;
        }
    }
    /* warn if array full and more grades remain */
    if (grades.numValues == ARRSZ && strpbrk (p, "+-0123456789")) {
        puts ("warning: array full and additional grades remain");
    }
    
    prngradeData (&grades);     /* output results */
}
(note: on Windows Ctrl + z is used to generate a manual EOF instead of Ctrl + d for Linux)
Example Use/Output
Your example:
$ ./bin/gradetype
Enter a student's grade type and grades (e.g. Quiz 41 20 90 81):
Quiz 55 53 60 70
type   : Quiz
grades : 55 53 60 70
Does it handle all 20 grades if provided?
$ ./bin/gradetype
Enter a student's grade type and grades (e.g. Quiz 41 20 90 81):
Daily 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
type   : Daily
grades : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
What if 21 are provided?
$ ./bin/gradetype
Enter a student's grade type and grades (e.g. Quiz 41 20 90 81):
Daily 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
warning: array full and additional grades remain
type   : Daily
grades : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
And invalid grades?
$ ./bin/gradetype
Enter a student's grade type and grades (e.g. Quiz 41 20 90 81):
Quiz 55 53 bananas 70
error: no digits converted:  bananas 70
type   : Quiz
grades : 55 53
There are many more things you can do, such as when faced with a no digits converted error, you can scan forward in the string to find the next (optional +/- followed by a) digit. You can then skip over the non-digit characters causing failure, etc... strtol() gives you that option with the detailed error reporting it provides.
Look things over and let me know if you have questions.