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

Kod - ANSI C - jedna linijka

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
206 wizyt
pytanie zadane 5 listopada 2018 w C i C++ przez gorgonkowa Obywatel (1,810 p.)

Hejka. Chciałabym się Was spytać, co mogłabym zmienić w tej linijce kodu, aby poprawnie się kompilowała w środowisku CodeBlocks?
W niej jest błąd:
 

    fprintf(pliczek, "%s %s %d %f", WprowadzStudenta(TDane *x));

A kod jest następujący:
 

#include <stdlib.h>
#include <stdio.h>
#define PLIK "plik.txt"

typedef struct
{
    char nazwisko[20], imie[20];
    int rok_ur;
    float srednia;
} TDane;

typedef struct
{
    TDane d;
    struct TElement* next;
} TElement;

typedef TElement* TWsk;

int WprowadzStudenta(TDane *x);
int WyswietlStudenta(TDane x);
int NaStos(TWsk *P, TDane x);
int ZeStosu(TWsk *P, TDane *x);
int WprowadzDane(TWsk *P);
int UsunStos(TWsk *P);
int WyswietlStos(TWsk P);
float ZwrocSrednia(TWsk P);
int NajwiekszyElement(TWsk P);

int main()
{
    FILE *pliczek;
    TDane x;
    TWsk P;
    P=NULL;
    WprowadzDane(&P);
    printf("\nWprowadzono nastepujace dane: \n");
    printf("Srednia: %.2f\n", ZwrocSrednia(P));
    printf("Najwiekszy element: %d\n", NajwiekszyElement(P));
    UsunStos(&P);
    pliczek = fopen(PLIK, "w");
    fprintf(pliczek, "%s %s %d %f", WprowadzStudenta(TDane *x));
    fclose(pliczek);
    fprintf(pliczek, "%s %s %d %f", WyswietlStudenta(TWsk P))
    return 0;
}

int WprowadzStudenta(TDane *x)
{
    printf("Podaj nazwisko: ");
    scanf("%s", x->nazwisko);
    printf("Podaj imie: ");
    scanf("%s", x->imie);
    printf("Podaj rok urodzenia: ");
    scanf("%d", &x->rok_ur);
    printf("Podaj srednia: ");
    scanf("%f", &x->srednia);
    return 0;
}

int WyswietlStudenta(TDane x)
{
    printf("%s %s %d %4.2f\n", x.nazwisko, x.imie, x.rok_ur, x.srednia);
    return 0;
}

int NaStos(TWsk *P, TDane x)
{
    TWsk Q;
    Q=(TElement*)malloc(sizeof(TElement));
    Q->d=x;
    Q->next=(*P);
    (*P)=Q;
    return 0;
}

int ZeStosu(TWsk *P, TDane *x)
{
    TWsk Q;
    if(P!=NULL)
    {
        Q=(*P);
        *x=Q->d;
        (*P)=Q->next;
        free(Q);
    }
    return 0;
}

int WprowadzDane(TWsk *P)
{
    int n, i;
    TDane x;
    printf("Dane ilu osob chcesz wprowadzic?: ");
    scanf("%d", &n);
    for(i=1; i<=n; i++)
    {
        printf("%d osoba: \n", i);
        WprowadzStudenta(&x);
        NaStos(&(*P), x);
    }
    return 0;
}

int UsunStos(TWsk *P)
{
    TDane x;
    while((*P)!=NULL)
    {
        ZeStosu(&(*P), &x);
        WyswietlStudenta(x);
    }
    return 0;
}

int WyswietlStos(TWsk P)
{
    while (P!=NULL)
    {
        WyswietlStudenta(P->d);
        P=P->next;
    }
    return 0;
}

float ZwrocSrednia(TWsk P)
{
    float sum_srednia = 0.f;
    int ilosc = 0;
    while(P!= NULL){
        sum_srednia += P->d.srednia;
        ++ilosc;
        P = P->next;
    }
    if( ilosc == 0)
        return 0.f;

    return  sum_srednia/ilosc;
}

int NajwiekszyElement(TWsk P)
{
    int najwiekszy = 0;
    int ile = 0;
    while(P!=NULL)
    {
        if(P->d.rok_ur>najwiekszy)
        najwiekszy = P->d.rok_ur;
        ++ile;
        P = P->next;
    }
    if(ile==0)
    {
        printf("Brak najwiekszego elementu!");
        return 0;
    }

    return najwiekszy;
}

Jak można zmienić trzeci argument funkcji, aby nie wyświetlał błędu w tamtej linijce? Błąd to "expected expression before TDane". Próbowałam 2 dni siedzieć nad rozwiązaniem, jednak nic mi nie potrafi do głowy przyjść :/ Bardzo bym była wdzięczna za pomoc.

2 odpowiedzi

0 głosów
odpowiedź 5 listopada 2018 przez RafalS VIP (122,820 p.)
Tdane* x

To deklaracja zmiennej. Argumentem do wprowadz studenta ma byc zmienna a nie deklaracja zmiennej.

TDane x;
fprintf(pliczek, "%s %s %d %f", WprowadzStudenta(&x));

 

komentarz 5 listopada 2018 przez gorgonkowa Obywatel (1,810 p.)
Hmm również próbowałam zrobić z tą zmienną wcześniej i nadal wyświetla się ten sam błąd :/
–1 głos
odpowiedź 5 listopada 2018 przez mbabane Szeryf (79,260 p.)

Pomijając to o czym pisze RafalS to może dlatego, że Wprowadź studenta zwraca pojedynczą wartość (prawdę mówiąc jest to trochę dla mnie niejasne, dlaczego te funkcje zwracają 0 od tak), a Ty w fprintf podajesz taki schemat: 

%s %s %d %f

więc kompilator oczekuje, że pojawi się 4 wartości tzn:

fprintf(pliczek, "%s %s %d %f", wartosc1, wartosc2, wartosc3, wartosc4);

http://cpp0x.pl/dokumentacja/standard-C/fprintf/455

Przeczytaj Opis szczegółowy

komentarz 5 listopada 2018 przez gorgonkowa Obywatel (1,810 p.)

Poprawiłam na takie coś:
 

    fprintf(pliczek, WprowadzStudenta(&x));

Teraz pokazuje błąd typu:
Warning: passing argument 2 of fprintf makes pointer from integer without a cast[-Wint-conversion]
note: expected const char* but argument is of type int

Program się już włącza, jednak po wprowadzeniu wszystkich danych, gdy program powinien się już zamknąć, przypuszczając, że chcę wpisać 2 osoby, to wpisze się ich dane, potem pokazują się dane na ekranie, ale błąd jest też taki, że znów program prosi o wpisanie danych. Dodatkowo, program tworzy plik tekstowy w folderze, jednak pusty, bez danych.

komentarz 5 listopada 2018 przez mbabane Szeryf (79,260 p.)

Źle wywolujesz funkcję fprintf, podajesz jej złe argumenty, zerknij w link, który Ci podesłałem.

Funkcja w C (i nie tylko w C), ma powiedzmy takie 4 elementy:

  1. Typ zwracany (wymagane, może nic nie zwracać, ale trzeba i tak podać typ void więc wymagane),
  2. Nazwę (wymagane),
  3. Argumenty, które przyjmuje (opcjonalne),
  4. Ciało (wymagane, ale może być puste).

zobacz na ten schemacik:

https://i.imgur.com/om8INDj.png

komentarz 5 listopada 2018 przez gorgonkowa Obywatel (1,810 p.)
Hmm... troszkę się zastanowiłam nad tym schemacikiem, próbowałam poczytać też co nieco o tym w google i... doszłam, nie wiem czy prawdziwych czy fałszywych wniosków, ale... czy czasami pisząc tego fprintf to powinien być zwracany typ, czyli chyba tego brakuje w kodzie, bo mam jedynie nazwę "pliczek", potem powinno być "%s %s %d %f", a zanim będzie WprowadzStudenta to chyba jeszcze powinno być określenie jakby... zmiennych wewnątrz tego argumentu, czyli chodzi o &nazwisko, &imie, &rok_ur, &srednia, a dopiero potem WprowadzStudenta(&x). Nic innego już mi do głowy nie przychodzi... :P
komentarz 5 listopada 2018 przez mbabane Szeryf (79,260 p.)

Znaczy można użyć funkcji, która coś zwraca, bez zapisywania tej wartości, czyli biorąc funkcję ze schematu, zadziała też tak:

funkcja(11, 'd'); //nie będzie błędu kompilacji

 

Cały czas, od początku tego posta piszę, że podajesz złe argumenty do fprintf, nie wiem czy czytałeś i sprawdzałeś co jest w tym linku, bo mam wrażenie, że nie.

Jeśli schemat, drukowania będzie taki (czyli drugi argument funkcji fprintf):

%s %s %d %f

to, po tym schemacie MUSI pojawić się kolejne 4 argumenty, które będą odpowiadały kolejno %s, %s, %d, %f:

Czyli konkretnie w Twoim przypadku powinno być:

fprintf(pliczek, "%s %s %d %f", x.imie, x.nazwisko, x.rok_ur, x.srednia);

A w kodzie który podesłałaś tak naprawdę było:

fprintf(pliczek, "%s %s %d %f", 0); //bład bo w schemacie podane są 4 elementy, a funkcja dostaje 1.

to zero wzięło się stąd, że funkcja WrowadzStudenta zwraca 0.

komentarz 5 listopada 2018 przez gorgonkowa Obywatel (1,810 p.)

Tak, czytałam tamten schemacik i właśnie o tym mówiłam, tylko może nie znam tych specjalistycznych słów żeby to określić, ale już zrozumiałam czemu tak a nie inaczej. Bardzo przepraszam za moją niewiedzę i dziękuję za pomoc. :)
Jedynie... mam małe pytanko, otóż w linijce:
 

    pliczek = fopen(PLIK, "w");

Mamy tam literkę "w", co już wiem, że oznacza, że to jakby tworzy plik do zapisu. Po skompilowaniu i wprowadzeniu danych, a następnie wyłączeniu konsoli, sprawdziłam w folderze plik, który powinien powstać, jednak w nim spotkałam takie znaczki:
"­l_v€@ Ě˙a 124 0.000000" --> Dlaczego powiedzmy tutaj jest coś takiego zamiast znaków wpisanych do konsoli? To też raczej nie wygląda mi na zapis binarny "w+b", więc nie wiem skąd się to wzięło. :P

komentarz 5 listopada 2018 przez mbabane Szeryf (79,260 p.)

Tak, czytałam tamten schemacik

W sumie miałem na myśli bardziej ten link z pierwszego posta, ale nie ważne, grunt, że zrozumiałaś o co chodzi.

 Bardzo przepraszam za moją niewiedzę i dziękuję za pomoc

Nie ma za co przepraszać. Cały czas starałem się tylko pisać tak abyś sama dochodziła do problemu, tak żebym nie musiał pisać gotowego rozwiązania, które było by do bezmyślnego skopiowania.

 

Na ostatnie pytanie, niestety nie znam odpowiedzi, nie programuje na co dzień w C więc nie chce walić głupot.

Sprawdź może to:

https://pl.wikibooks.org/wiki/C/Czytanie_i_pisanie_do_plików

 

Jedyne na co mogę jeszcze zwrócić uwagę to:

fprintf(pliczek.... 
fclose(pliczek);
fprintf(pliczek, ...

Chodzi o to, że zapisujesz do pliku, zamykasz go, i znowu zapisujesz. Zamknięcie zasobu robi się po zakończeniu na nim wszystkich prac. Jeśli go zamkniesz to musisz go otworzyć od nowa.

Podobne pytania

0 głosów
1 odpowiedź 1,215 wizyt
pytanie zadane 30 października 2018 w C i C++ przez gorgonkowa Obywatel (1,810 p.)
0 głosów
1 odpowiedź 1,010 wizyt
pytanie zadane 8 kwietnia 2018 w C i C++ przez giedymin33 Początkujący (290 p.)
+1 głos
1 odpowiedź 280 wizyt
pytanie zadane 4 września 2016 w C i C++ przez Iamhexi Obywatel (1,330 p.)

93,187 zapytań

142,203 odpowiedzi

322,022 komentarzy

62,513 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2345p. - dia-Chann
  2. 2306p. - Łukasz Piwowar
  3. 2295p. - Łukasz Eckert
  4. 2282p. - CC PL
  5. 2252p. - Tomasz Bielak
  6. 2219p. - Łukasz Siedlecki
  7. 2215p. - rucin93
  8. 2201p. - Michal Drewniak
  9. 2156p. - Marcin Putra
  10. 2152p. - Adrian Wieprzkowicz
  11. 2105p. - Mikbac
  12. 1941p. - Anonim 3619784
  13. 1733p. - rafalszastok
  14. 1480p. - Michał Telesz
  15. 1469p. - ssynowiec
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...