• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Język C, pliki i zapisywanie pewnych podzielnych liczb.

42 Warsaw Coding Academy
0 głosów
848 wizyt
pytanie zadane 28 marca 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
edycja 28 marca 2020 przez Hubertius

Hej :)

Mam problem z zadaniem o następującej treści:

Napisz program, który będzie pobierał od użytkownika liczby całkowite, aż do wprowadzenia liczby 0 i zapisywał je do plików tekstowych, w następujący sposób:

do pliku 2.txt wszystkie liczby podzielne przez 2,
do pliku 3.txt podzielne przez 3,
do pliku 5.txt podzielne przez 5,
a do pliku 0.txt pozostałe.
Każda liczba ma znajdować się w nowym wierszu.

Jeżeli operacje tworzenia któregoś z plików nie powiedzie się, program powinien wyświetlić komunikat Couldn't create file i zakończyć działanie z kodem błędu 5.

W przypadku sukcesu program powinien wyświetlić komunikat Files saved i zwrócić wartość 0.

Przykład interakcji z programem - sukces:

Podaj liczby:⏎
0⏎
Files saved
Przykład interakcji z programem - sukces:

Podaj liczby:⏎
1 1 39 93 38 -54 -51 8 34 25 57 37 -87 6 -4 93 -91 34 57 -95 4 -12 -27 33 -51 -48 -50 -71 -45 38 -22 -23 30 1 92 -96 15 -36 14 13 35 -40 -54 -32 51 78 -17 -9 30 97 -77 -71 1 -92 -67 -64 80 88 -9 1 -49 -71 85 -90 17 33 62 1 -84 1 2 65 37 -38 98 -51 58 5 -62 -52 93 -8 -27 -100 -31 34 18 -7 -61 -68 1 85 -85 -84 55 -45 71 -4 7 70 -17 21 -49 95 -60 -93 63 94 74 -38 -9 -72 97 -26 -74 -23 -85 -84 0⏎
Files saved
Pliki wyjściowe: 0.txt 2.txt 3.txt 5.txt

Przykład interakcji z programem - brak możliwości zapisu na dysk:

Couldn't create file⏎
Uwaga

W programie nie wolno używać funkcji alokujacych pamięć.
W programie nie wolno używać operatora [].

Oto mój kod do niego:

#include <stdio.h>
#include <stdlib.h>


int main()
{



    char * nazwa_2= (char*)"2.txt";
    char * nazwa_3= (char*)"3.txt";
    char * nazwa_5= (char*)"5.txt";
    char * nazwa_na_pozostale=(char*)"0.txt";
    FILE * f_2=fopen(nazwa_2,"w");
    if(f_2 == NULL)
    {
        printf("Couldn't create file");
        return 5;
    }
    FILE *f_3=fopen(nazwa_3,"w");
    if(f_3==NULL)
    {
        //fclose(f_3);
        printf("Couldn't create file");
        return 5;
    }
    FILE *f_5=fopen(nazwa_5,"w");
    if(f_5==NULL)
    {
        //fclose(f_5);
        printf("Couldn't create file");
        return 5;
    }
    FILE *f_pozostale=fopen(nazwa_na_pozostale,"w");
    if(f_pozostale==NULL)
    {
        //fclose(f_pozostale);
        printf("Couldn't create file");
        return 5;
    }
    int liczba=-1;
    int i=0;
    printf("Podaj liczby: \n");
    while(liczba != 0)
    {
        scanf("%d",&liczba);
        if(liczba == 0)
        {
            break;
        }
        if( liczba%2 == 0 )
        {
            fprintf(f_2,"%d\n",liczba);
        }
        if( liczba%3 == 0 )
        {
            fprintf(f_3,"%d\n",liczba);
        }
        if( liczba%5 == 0)
        {
            fprintf(f_5,"%d\n",liczba);
        }
        if( liczba%2 != 0 && liczba%5 != 0 && liczba%3 != 0 )
        {
            fprintf(f_pozostale,"%d\n",liczba);
        }
        i++;
    }





    fclose(f_2);
    fclose(f_3);
    fclose(f_5);
    fclose(f_pozostale);
    printf("File saved");
    return 0;
}

A problem z tym zadaniem mam dwa, z czego pierwszy wynika u mnie z następującego podpunktu:

W programie nie wolno używać operatora [].

Próbowałem rozwiązać problem w ten sposób:

char * nazwa_2= (char*)"2.txt";
char * nazwa_3= (char*)"3.txt";
char * nazwa_5= (char*)"5.txt";
char * nazwa_na_pozostale=(char*)"0.txt";

Ale na testach zadania wychodzi mi coś takiego:

Line	Id	CWE	Severity	Message
main.c
28	resourceLeak	775	error	Resource leak: f_2
35	resourceLeak	775	error	Resource leak: f_2
35	resourceLeak	775	error	Resource leak: f_3
42	resourceLeak	775	error	Resource leak: f_2
42	resourceLeak	775	error	Resource leak: f_3
42	resourceLeak	775	error	Resource leak: f_5

No i do tego jest ten problem, przez który to zadanie będzie wciąż niezaliczone. Oto i on:

### Testy funkcji main() ### 
⏎
TEST 2: Reakcja na brak możliwości otworzenia pliku (fopen zwróci NULL przy drugim wywołaniu)⏎
***START***⏎
Couldn't create file⏎
***END***⏎
Wynik: SUKCES⏎
### RLDebug :: Analiza wycieku zasobów ### 
Wszystkie bloki pamięci zostały pomyślnie zwolnione - brak wycieków.⏎
⏎
Niezamknięte pliki:⏎
--------------------------------------------⏎
 ID  Nazwa                     Plik źródłowy⏎
     Tryb                      Numer linii  ⏎
--------------------------------------------⏎
 1   2.txt                     main.c⏎
     w                         16⏎
--------------------------------------------⏎
Liczba niezamkniętych plików: 1⏎
Nie wykryto uszkodzenia sterty.⏎
⏎
### Podsumowanie ### 
   Testy dostępne:    1 (AVAIL)⏎
         Wykonane:    1 (DONE)⏎
   Testy poprawne:    1 (PASSED)⏎
Testy niepoprawne:    0 (FAILED)⏎
      Ostrzeżenia:    0 (WARNINGS)⏎
  Wycieki zasobów:    1 (LEAKS)⏎
Program zakończony; kod błędu=0 (Ok)

Test został przerwany; Wykryto wycieki zasobów (pamięć, pliki, etc...). Popraw swój kod.

Nie do końca rozumiem tego testu. Jaki plik jest niezamykany? Jeżeli f_2 jest NULL no to powinien być printf z komunikatem i return. Dla pewności sprawdzałem rozwiązanie z fclose w tejże instrukcji warunkowej i też to nie było rozwiązanie problemu. Wiecie może o co tu biega?  :/

1 odpowiedź

+1 głos
odpowiedź 28 marca 2020 przez tangarr Mędrzec (155,180 p.)
wybrane 28 marca 2020 przez Hubertius
 
Najlepsza

Nie zamykasz plików w przypadku błędów. Jeżeli uda ci się otworzyć wszystkie pliki oprócz ostatniego to zostawiasz 3 otwarte pliki.
W języku C musisz pamiętać aby zwolnić wszystkie zaalokowane zasoby przy wszystkich wyjściach z funkcji. Dla pewnej automatyzacji stosuje się pewną sztuczkę:
 

int funkcja() {
    FILE *file1 = NULL;
    FILE *file2 = NULL;
    char *pointer1 = NULL;
    int returnCode = 0;
    
    file1 = fopen("plik1", "r");
    if (file1 == NULL) {
        returnCode = 1;
        goto on_error;
    }
    file2 = fopen("plik2", "r");
    if (file2 == NULL) {
        returnCode = 2;
        goto on_error;
    }
    pointer1 = (char*) malloc(1024);
    if (pointer1 == NULL) {
        returnCode = 3;
        goto on_error;
    }
    /* JAKIEŚ OBLICZENIA */

    on_error:
    free(pointer1);
    fclose(file2);
    fclose(file1);
    return returnCode;
}

 

komentarz 28 marca 2020 przez Hubertius Bywalec (2,970 p.)
Bardzo dziękuję za tę cenną uwagę. Zadanie udało mi się teraz wykonać.  :)

Podobne pytania

0 głosów
1 odpowiedź 1,193 wizyt
0 głosów
0 odpowiedzi 239 wizyt
pytanie zadane 31 marca 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
0 głosów
0 odpowiedzi 470 wizyt
pytanie zadane 30 marca 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

93,389 zapytań

142,385 odpowiedzi

322,547 komentarzy

62,749 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
...