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

W jaki sposób wprowadzić tablicę char do struktury poprzez wpisanie ciągu znaków

VPS Starter Arubacloud
0 głosów
377 wizyt
pytanie zadane 10 maja 2019 w C i C++ przez Białozór Użytkownik (750 p.)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>



struct Osoba {
	char imie[20];
	char nazwisko[20];
	int rokurodzenia;
	char numerkonta[27]; // +1
	char nazwabanku[20];
	int kwota;



};


struct Osoba TablicaOsob[] = { 
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13248 },
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13246 } ,
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13247 } };


int liczba_osob =3;
int main(void) {
    while(1)
    {
    
	    int suma; 
        suma=0;
        
        

        
        int najwieksza;
        najwieksza=0;
		char wybor = 0;
    
    printf(" Jeśli chcesz wyświetlić pełną listę kont wpisz 1  \n jeśli chcesz sprawdzić który posiadacz konta przechowuje na nim największą a który najmniejszś kwotę wpisz 2 \n jeśli chcesz poznać sumę pieniędzy wszystkich urzytkowników wpisz 3 \n (jesli chcesz wprowadzic nowa osobe wpisz 4)");

	wybor = 0;
	wybor=getchar();

	switch(wybor)
	{
	    case '1':
	    printf("W tablicy struktur ListaOsoba typu Osoba  mamy nastepujace dane:\n");
	    for (int i = 0; i < liczba_osob; i++) {
		printf("TablicaOsob[%d]\n", i);
		printf("imie: %s,   nazwisko: %s\n,	rokurodzenia: %d\n, numerkonta: %s\n,	nazwabanku: %s\n,	kwota: %i\n \n", TablicaOsob[i].imie, TablicaOsob[i].nazwisko, TablicaOsob[i].rokurodzenia, TablicaOsob[i].numerkonta, TablicaOsob[i].nazwabanku, TablicaOsob[i].kwota);
	    }
	    
	    break;
	    
	    case '2':
		najwieksza = TablicaOsob[0].kwota;
	    
		for (int i = 1; i < liczba_osob; i++)// 2 
	    {
	        if( TablicaOsob[i].kwota > najwieksza )
	        {
	           najwieksza = TablicaOsob[i].kwota;
	        }
	    }
	    printf("najwieksza: %i\n \n", najwieksza);
	    break;
	    
	    case '3':

	    for (int i = 0; i < liczba_osob; i++) 
	    {
	        
	        suma=suma+TablicaOsob[i].kwota;
	    }
        printf("suma: %i\n \n", suma);

	    break;
	    
	    case '4':
	    liczba_osob =liczba_osob +1;
	    
	    printf("wpisz imie:");
	    

	    scanf("%s", TablicaOsob[liczba_osob].imie[20]);
	    printf("imie nowe: %s\n" , &TablicaOsob[liczba_osob].imie); 


	    /*
        cin.ignore();
        
	    printf("wpisz nazwisko:");
	    cin >> TablicaOsob[liczba_osob].nazwisko;
        cin.ignore();
	    printf("wpisz rok urodzenia:");
	    cin >> TablicaOsob[liczba_osob].rokurodzenia;
        cin.ignore();
	    printf("wpisz numer konta:");
	    cin >> TablicaOsob[liczba_osob].numerkonta;
        cin.ignore();
	    printf("wpisz nazwe banku:");
	    cin >> TablicaOsob[liczba_osob].nazwabanku;
        cin.ignore();
	    printf("wpisz kwote:");
	    cin >> TablicaOsob[liczba_osob].kwota;
        cin.ignore();
        */
        
	    break;
	    
	}
	//printf("wyszedłem z zewnętrznej pętli while \n");
}
	

	
}

Problem jest następujący: po wprowadzeniu imienia poprzez wybranie 4 a następnie próbie wyświetlenia go przy pomocy wpisania 1 następuje wyświetlenie losowych symboli.  Skoro pobranie imienia następuje poprawnie ( co, jeśli dobrze rozumiem pokazywać powinien printf z linii 89 )  to dlaczego próba wyświetlenia bezpośrednio z tablicy kończy się błędem?

Istotne fragmenty programu znajdują się w liniach 9 i 88.

1 odpowiedź

+1 głos
odpowiedź 11 maja 2019 przez niezalogowany
wybrane 11 maja 2019 przez Białozór
 
Najlepsza

mi tam działa po drobnych korektach, chociaż nie znam się na c

no niekoniecznie prawidłowo (tj pierwsze imię błędnie następne już ok)

 88 - scanf("%s", TablicaOsob[liczba_osob].imie); // wskaznik na pierwszą literę ?
 89 -   printf("imie nowe: %s\n" , &TablicaOsob[liczba_osob].imie);

case 27 : return 0; // wyjście z pętli

no i nie rozumiem gdzie rezerwujesz pamięć dla tablicy, czy nadpisujesz gdzie popadnie? Co jest zabronione chyba.

Jak nie specjalnie to jakiś kontener by się przydał (wskaznik next, new element)

no i jeszcze

linia 42 
printf("wpisz 1\t  Jeśli chcesz wyświetlić pełną listę kont \n");
 printf("wpisz 2\t  Jeśli chcesz sprawdzić który posiadacz konta przechowuje na nim największą a który najmniejszś kwotę \n");
 printf("wpisz 3\t  Jeśli chcesz poznać sumę pieniędzy wszystkich urzytkowników  \n ");
 printf("wpisz 4\t  Jesli chcesz wprowadzic nowa osobe");

 

komentarz 11 maja 2019 przez Białozór Użytkownik (750 p.)

Słusznie zauważyłeś brak zarezerwowana miejsca nie tylko na tablice, lecz generalnie na wprowadzane osoby. Zmieniłam to w sposób następujący:  (wstawiłam 10)

struct Osoba TablicaOsob[10] = { 
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13248 },
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13246 } ,
{ "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13247 } };
 

Nie sprawiło to by program zapisywał imie poprawnie z tego powodu pomimo znajdowania się w deklaracji struktury rozmiaru imie:

struct Osoba {
    char imie[20];
    char nazwisko[20];
    int rokurodzenia;
    char numerkonta[27]; // +1
    char nazwabanku[20];
    int kwota;

wprowadziłam dodatkowo imie[20] zamiast imie:

scanf("%s", TablicaOsob[liczba_osob].imie[20]);
        printf("imie nowe: %s\n" , &TablicaOsob[liczba_osob].imie); 

Znalazłam jeszcze następujący film: https://www.youtube.com/watch?v=M9Poj75qWWY i próbowałam odnaleźć różnice między nim a moim programem. Wolałabym na razie nie korzystać ze wskaźników, ponieważ pomimo że czytałam o tym jak działają nie wiem jeszcze jak zastosować je w tym programie, oficjalnie będą wprowadzone na ćwiczeniach w przyszłym tygodniu.

Printf poprawiłam.

komentarz 11 maja 2019 przez niezalogowany
edycja 11 maja 2019

generalnie to ja w C jestem bardzo słaby, ale mniej więcej twój program działa prawidłowo

tylko nie wyświetla ostatnio dodanego imienia

linia 51    for (int i = 0; i <= liczba_osob; i++) // bo liczysz od 0 czyli jak  liczba_osob=3, to 4 osoby, liczba_osob=4, to 5 osob itd.

ja się też na wskaźnikach nie znam i na charach ale

definicja char slowo [20]; to oznacza tablicę gdzie możesz zmieścić 19 znaków plus '\0'

a slowo [20] oznacza 21 znak tablicy (czyli pierwszy poza tablicą np imie[20]==nazwisko[0] lub też inny obszar pamięci nie wiadomo gdzie);

a slowo chyba oznacza wskaźnik na element slowo[0] tak przynajmniej jest w tablicach charach jest troszeczkę inaczej ale nie pamiętam już, jak tylko mogę to używam std::string w c++;

a tu ten kod co u mnie działa no może nie do końca poprawnie ale wypisuje i wpisuje imię reszty nie sprawdzałem 2 to wyjście z programu;

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

struct Osoba {
    char imie[20];
    char nazwisko[20];
    int rokurodzenia;
    char numerkonta[27]; // +1
    char nazwabanku[20];
    int kwota;
};


struct Osoba TablicaOsob[10] = {
    { "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13248 },
    { "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13246 },
    { "Karol","Kot",1998,"31415926535897932384626433","Bank Bank",13247 }
};

static int liczba_osob =3;
int main(void) {
    while(1) {

        int suma;
        suma=0;

        int najwieksza;
        najwieksza=0;
        char wybor = 0;


        printf("wpisz 1\t  Jeśli chcesz wyświetlić pełną listę kont \n");
        printf("wpisz 2\t  Jeśli chcesz sprawdzić który posiadacz konta przechowuje na nim największą a który najmniejszś kwotę \n");
        printf("wpisz 3\t  Jeśli chcesz poznać sumę pieniędzy wszystkich urzytkowników  \n ");
        printf("wpisz 4\t  Jesli chcesz wprowadzic nowa osobe");

        wybor = 0;
        wybor=getchar();

        switch(wybor) {
        case '1':
            printf("W tablicy struktur ListaOsoba typu Osoba  mamy nastepujace dane:\n");
            for (int i = 0; i < liczba_osob; i++) {
                printf("TablicaOsob[%d]\n", i);
                printf("imie: %s,   nazwisko: %s\n, rokurodzenia: %d\n, numerkonta: %s\n,   nazwabanku: %s\n,   kwota: %i\n \n", TablicaOsob[i].imie, TablicaOsob[i].nazwisko, TablicaOsob[i].rokurodzenia, TablicaOsob[i].numerkonta, TablicaOsob[i].nazwabanku, TablicaOsob[i].kwota);
            }

            break;

        case '2':
            najwieksza = TablicaOsob[0].kwota;

            for (int i = 1; i < liczba_osob; i++) { // 2
                if( TablicaOsob[i].kwota > najwieksza ) {
                    najwieksza = TablicaOsob[i].kwota;
                }
            }
            printf("najwieksza: %i\n \n", najwieksza);
            return 0;
            break;

        case '3':
            for (int i = 0; i < liczba_osob; i++) {

                suma=suma+TablicaOsob[i].kwota;
            }
            printf("suma: %i\n \n", suma);
            break;

        case '4':


            printf("wpisz imie:");


            scanf("%s", TablicaOsob[liczba_osob].imie);
            printf("imie nowe: %s\n", TablicaOsob[liczba_osob].imie);
            liczba_osob =liczba_osob +1;


            /*
            cin.ignore();

            printf("wpisz nazwisko:");
            cin >> TablicaOsob[liczba_osob].nazwisko;
            cin.ignore();
            printf("wpisz rok urodzenia:");
            cin >> TablicaOsob[liczba_osob].rokurodzenia;
            cin.ignore();
            printf("wpisz numer konta:");
            cin >> TablicaOsob[liczba_osob].numerkonta;
            cin.ignore();
            printf("wpisz nazwe banku:");
            cin >> TablicaOsob[liczba_osob].nazwabanku;
            cin.ignore();
            printf("wpisz kwote:");
            cin >> TablicaOsob[liczba_osob].kwota;
            cin.ignore();
            */

            break;

        case 27:
            return 0;

        }
        //printf("wyszedłem z zewnętrznej pętli while \n");
    }
}

 

 

komentarz 11 maja 2019 przez Białozór Użytkownik (750 p.)
Dziękuję, program działa! Lecz dlaczego wprowadzenie  static int liczba_osob zamiast int oraz przesunięcie liczba_osob =liczba_osob +1; na koniec 4 pętli pomogło?
komentarz 11 maja 2019 przez niezalogowany
to static to akurat nie ma znaczenia,  to co pisałem wcześniej

liczba_osob - podajesz 3, a masz 4 osoby {0,1,2,3} do {0,1,2} masz przypisane wartości a {3} jest pusta, i przeniesienie na koniec dało to, że wpisujesz najpierw do {3}, a później tworzysz nowy rekord.
komentarz 11 maja 2019 przez Białozór Użytkownik (750 p.)
Zrozumiałam, dziękuję.

Podobne pytania

0 głosów
1 odpowiedź 405 wizyt
pytanie zadane 24 stycznia 2023 w C i C++ przez k0n6710r Nowicjusz (160 p.)
0 głosów
1 odpowiedź 550 wizyt
0 głosów
3 odpowiedzi 452 wizyt
pytanie zadane 27 kwietnia 2019 w C i C++ przez miodowy Nowicjusz (120 p.)

92,416 zapytań

141,222 odpowiedzi

318,985 komentarzy

61,831 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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...