Home > OS >  C code works on my PC but on grader system doesn't
C code works on my PC but on grader system doesn't

Time:01-09

I have a problem with the code that I wrote. I have some test cases that have the results for the same. When I run these TC on my laptop the result is as expected, but when I upload code to my class grader only the first one doesn't work and says that the algorithm is not good or that there is some infinite loop. I think that the code is good; maybe I am wrong. What do you think?

Test Case 1:

[11:25] Bogadi Alen: Kameleon
[11:25] Begovic Amir: Magarac
[11:25] Novak Anel: Tapir
[11:25] Milanja Ante: Jelen
[11:25] Mavracic Antonio: Morski pas
[11:35] Dutkovic Ivan: Vuk
[11:35] Kulic Ivan: Orao
[11:53] Prekratic Ivan: Kameleon
[11:53] Vuletic Jaksa: Krava
[11:53] Bakaric Jan: Kameleon
[11:53] Mladar Jan: Majmun
[12:13] Bakran Josip: Slon
[12:13] Profesor Ivan: Kameleon

Expected result:

Broj studenata koji su pogodili zivotinju: 3 od 12.

Studenti koji su pogodili zivotinju:
Bogadi Alen
Prekratic Ivan
Bakaric Jan

Test Case 2:

[14:27] Profesor Ivan: Pas

Expected result:

Vise srece drugi put!

Here I put 2 TC and the first one is not working properly...

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

int main()
{
    //x-igralo, y-pogodilo
    int x = 0, y = 0;
    //da li prvi put unosim podatke
    int prviput = 1;
    char profime[9] = "Profesor";
    int brojredova = 1;
    //alociranje memorije-pocetno
    char** ime = (char**)calloc(brojredova, sizeof(char*));
    char** prezime = (char**)calloc(brojredova, sizeof(char*));
    char** zivotinja = (char**)calloc(brojredova, sizeof(char*));
    char time[30];
    char tprez[30];
    char tzivotinja[30];

    do {
        //trenutno predstavlja index reda
        int indx = brojredova - 1;
        if (prviput)
        {
            scanf("%*c%*c%*c%*c%*c%*c%*c %[^ ] %[^:]%*c %[^\n]", time, tprez, tzivotinja);
            int len = strlen(tzivotinja);

            //alociram memoriju za duzinu imena,prezimena
            *(ime   indx) = (char*)calloc(strlen(time), sizeof(char));
            *(prezime   indx) = (char*)calloc(strlen(tprez), sizeof(char));
            *(zivotinja   indx) = (char*)calloc(strlen(tzivotinja), sizeof(char));

            strcpy(*(ime   indx), time);
            strcpy(*(prezime   indx), tprez);
            strcpy(*(zivotinja   indx), tzivotinja);

            //pretvaranje svih slova u mala zbog kasnije usporedbe
            for (int j = 0; j < len; j  )
            {
                if (isupper(*(*(zivotinja   indx)   j)))
                {
                    *(*(zivotinja   indx)   j)  = 32;
                }
            }
            x  ;
            prviput = 0;
            //ako je unesen korisnik koji nije profesor, alocira se jos 1 red za sljedeceg korisnika
            if (strcmp("Profesor", time) != 0)
            {
                brojredova  ;

                ime = (char**)realloc(ime, brojredova * sizeof(char*));
                prezime = (char**)realloc(prezime, brojredova * sizeof(char*));
                zivotinja = (char**)realloc(zivotinja, brojredova * sizeof(char*));
            }

        }
        else
        {

            scanf("%*c%*c%*c%*c%*c%*c%*c%*c %[^ ] %[^:]%*c %[^\n]", time, tprez, tzivotinja);
            int len = strlen(tzivotinja);
            //alociram memoriju za duzinu imena,prezimena
            *(ime   indx) = (char*)calloc(strlen(time), sizeof(char));
            *(prezime   indx) = (char*)calloc(strlen(tprez), sizeof(char));
            *(zivotinja   indx) = (char*)calloc(strlen(tzivotinja), sizeof(char));

            strcpy(*(ime   indx), time);
            strcpy(*(prezime   indx), tprez);
            strcpy(*(zivotinja   indx), tzivotinja);

            //pretvaranje svih slova u mala zbog kasnije usporedbe
            for (int j = 0; j < len; j  )
            {
                if (isupper(*(*(zivotinja   indx)   j)))
                {
                    *(*(zivotinja   indx)   j)  = 32;
                }
            }
            x  ;
            //ako je unesen korisnik koji nije profesor, alocira se jos 1 red za sljedeceg korisnika
            if (strcmp("Profesor", time) != 0)
            {
                brojredova  ;

                ime = (char**)realloc(ime, brojredova * sizeof(char*));
                prezime = (char**)realloc(prezime, brojredova * sizeof(char*));
                zivotinja = (char**)realloc(zivotinja, brojredova * sizeof(char*));
            }
        }

    } while (strcmp("Profesor", time) != 0);
    x--;

    for (int i = 0; i <= x - 1; i  )
    {
        if ((strcmp(*(zivotinja   i), *(zivotinja   brojredova - 1)) == 0) || (strstr(*(zivotinja   i), *(zivotinja   brojredova - 1)) != NULL))
        {
            y  ;
        }
    }

    //x-odirali
    if (x != 0)
    {
        printf("Broj studenata koji su pogodili zivotinju: %d od %d.\n\n", y, x);
        if (y == 0)
        {
            printf("Vise srece drugi put!");
        }
        else
        {
            printf("Studenti koji su pogodili zivotinju:\n");

            for (int i = 0; i <= x - 1; i  )
            {
                if ((strcmp(*(zivotinja   i), *(zivotinja   brojredova - 1)) == 0) || (strstr(*(zivotinja   i), *(zivotinja   brojredova - 1)) != NULL))
                {
                    printf("%s %s\n", *(ime   i), *(prezime   i));
                }
            }           
        }
    }
    else
    {
        printf("Vise srece drugi put!");
    }
}

CodePudding user response:

At least these problems:

Parsing is dodgy

Input is line orientated, but "%*c%*c%*c%*c%*c%*c%*c %[^ ] %[^:]%*c %[^\n]" readily can go pass the line.

The best way to read a line from stdin is fgets(), then parse.

Use width limits. Consider using " %n" to detect successful end of parsing.

#define LINE_SZ 200
char buf[LINE_SZ];

if (fgets(buf, sizeof buf, stdin)) {
  char time[30];
  char tprez[30];
  char tzivotinja[30];
  int n = 0;
  // Sample data: "[11:25] Mavracic Antonio: Morski pas"
  sscanf(buf, "[ )[^]]] )[^:]: )[^\n] %n", 
      time, tprez, tzivotinja, &n);
  if (n == 0 || buf[n]) {
    puts("failed to parse all or extra junk.");
  } else {
    printf("time:<%s> tprez:<%s> tzivotinja:<%s>\n", 
        time, tprez, tzivotinja);
  }
}

"[ )[^]]] )[^:]: )[^\n] %n" break down:

  • "[" Parse a `'['.
  • " " Parse optional whitespaces.
  • ")[^]]" Parse 1 - 29 non-']' characters, save, append \0.
  • "]" Parse a `']'.
  • " " Parse optional whitespaces.
  • ")[^:]" Parse 1 - 29 non-':' characters, save, append \0.
  • ":" Parse a `':'.
  • " " Parse optional whitespaces.
  • ")[^\n]" Parse 1 - 29 non-'\n' characters, save, append \0.
  • " " Parse optional whitespaces.
  • "%n" Save scan offset.

Wrong allocation size

Need 1 more for a string. Cast is not needed.

// *(ime   indx) = (char*)calloc(strlen(time), sizeof(char)); // Bad
*(ime   indx) = calloc(strlen(time)   1, sizeof(char));
...
strcpy(*(ime   indx), time);

Avoid magic number

Why 32? Why not 'a' - 'A'? Or better, use tolower()

        //if (isupper(*(*(zivotinja   indx)   j))) {
        //  *(*(zivotinja   indx)   j)  = 32;
        //}

        *(*(zivotinja   indx)   j) = tolower(*(*(zivotinja   indx)   j));
  •  Tags:  
  • Related