Problem z wczytywaniem danych do składników struktury.

0

Witam,
Mam program do napisania który wczytuje dane do tablicy 3 struktur o składnikach: imię, drugie imię, nazwisko oraz pesel. Program ma potem wyświetlać uporządkowane dane. Jednak po podaniu imienia wyskakuje mi komunikat o błędzie, który sam stworzyłem przy pomocy pętli while, po drugim razie wpisania imienia powinien chyba być znowu błąd (skoro za pierwszym razem wpisałem dobre imię a za drugim razem to samo wpisałem) a tutaj przechodzi mi do wczytywania drugiego imienia. Tak wygląda pętla z warunkiem wczytująca imię:

     puts("\nPodaj imie:");
     while(fgets(osoba_parametr[i].imiona_zmienna.p_imie, 24, stdin)==NULL || osoba_parametr[i].imiona_zmienna.p_imie[0]=='\n');
            {
                puts("\nNie podano imienia, sprobuj ponownie...");
                while((ch=getchar())!='\n');
            }

Czy coś jest w niej nie tak? Oczywiście while((ch=getchar())!='\n'); ma płukać bufor ze śmieci (nie wiem czy na pewno to będzie potrzebne może ktoś wie).

A tak wygląda cały program:

#include <stdio.h>
#include <string.h>

int i;
char ch;
    struct imiona {
       char p_imie[24];
       char d_imie[24];
       char nazwisko[24];
    } imiona_zmienna;

    struct osoba  {
       struct imiona imiona_zmienna;
       char pesel[11];
    } osoba_zmienna[3];


void pobierz_tablice(struct osoba * osoba_parametr);
void pokaz_tablice(struct osoba * osoba_paramter);

int main(void)
{

    pobierz_tablice(osoba_zmienna);
    pokaz_tablice(osoba_zmienna);
    puts("\nNacisnij [enter], aby wyjsc");
    getchar();
    return 0;
} 

void pobierz_tablice(struct osoba * osoba_parametr)
{
    puts("\nPodaj 3 zestawy danych na temat osob\n");
    for(i=0; i<3; i++)
        {
            puts("\nPodaj imie:");
            while(fgets(osoba_parametr[i].imiona_zmienna.p_imie, 24, stdin)==NULL || osoba_parametr[i].imiona_zmienna.p_imie[0]=='\n');
                {
                    puts("\nNie podano imienia, sprobuj ponownie...");
                    while((ch=getchar())!='\n');
                }
            
            puts("\nPodaj drugie imie lub wcisnij [enter] na poczatku wiersza gdy go nie ma: ");
            fgets(osoba_parametr[i].imiona_zmienna.d_imie, 24, stdin);
            while((ch=getchar())!='\n');
            puts("\nPodaj nazwisko:");
            while(fgets(osoba_parametr[i].imiona_zmienna.nazwisko, 24, stdin)==NULL || osoba_parametr[i].imiona_zmienna.nazwisko[0]=='\n');
                {
                    puts("\nNie podano nazwiska, sprobuj ponownie...");
                    while((ch=getchar())!='\n');
                }
            while((ch=getchar())!='\n');
            puts("\nPodaj pesel:");
            while(fgets(osoba_parametr[i].pesel, 12, stdin)==NULL || strlen(osoba_parametr[i].pesel)!=11)
                {
                    puts("\nNieprawidlowy pesel, sprobuj ponownie...");
                     while((ch=getchar())!='\n');
                }
            while((ch=getchar())!='\n');
        }
    return;
}

void pokaz_tablice(struct osoba * osoba_parametr)
{
    puts("\nZebrano nastepujace dane:\n ");
    for(i=0; i<3; i++)
        {
            if(osoba_parametr[i].imiona_zmienna.d_imie[0]=='\n')
                printf("%26s,     %-26s\n", osoba_parametr[i].imiona_zmienna.p_imie, osoba_parametr[i].pesel);
            else
                printf("%26s, %c. %-26s\n", osoba_parametr[i].imiona_zmienna.p_imie, osoba_parametr[i].imiona_zmienna.d_imie[0], osoba_parametr[i].pesel);
        }
    return;
}

Proszę bardzo o pomoc, nie mogę już dłużej stać w miesjcu przez ten program i dlatego piszę o tym na forum.

0

ogólnie w while warunki są zbyteczne np. while ch!='\n' (przy podaniu peselu n.p) a do imienia to warunek w petli rozbij na dwa warunki. Najpierw sprawdzaj

while(fgets(osoba_parametr[i].imiona_zmienna.p_imie, 24, stdin)==NULL); 

a dopiero później

osoba_parametr[i].imiona_zmienna.p_imie[0]=='\n' 
0

Dzięki za wskazówkę, zrozumiałem to tak i zmieniłem na coś takiego:

 while(scanf("%24s", &osoba_parametr[i].imiona_zmienna.p_imie)==0)
                if(osoba_parametr[i].imiona_zmienna.p_imie[0]=='\n')
                     {
                          puts("\nNie podano imienia, sprobuj ponownie...");
                          while((ch=getchar())!='\n');
                     }

Tylko teraz jest taki problem, że jak na początku wiersza nie wpisze nic i wcisnę enter to nic się nie dzieje, a chyba powinien pojawić się komunikat.

1
while // wczytujemy cały wiersz może być że spacją
  (
   // NULL tylko przy przekierowaniu i jeżeli plik się skonczył
   // jeżeli już dostałeś NULL'a to więcej nic nie wczytasz
   fgets(osoba_parametr[i].imiona_zmienna.p_imie, 24, stdin)!=NULL 
   &&
   osoba_parametr[i].imiona_zmienna.p_imie[0]=='\n'
  )
  {
   puts("Nie podano imienia, sprobuj ponownie...\n");
  }
// szukamy entera
char *ptr=strchr(osoba_parametr[i].imiona_zmienna.p_imie,'\n');
if(!ptr) // brak entera, w buforze coś zostało
  {
   while((ch=getchar())!='\n');
  }
else *ptr=0; // ewentualnie usuwamy tego entera z napisu 

lub:

scanf("%23s", osoba_parametr[i].imiona_zmienna.p_imie);
while((ch=getchar())!='\n'); // scanf zostawił entera
0

Przepisałem do swojego programu dokładnie drugą metodę i nadal jak nic nie wpiszę nie pojawia się komunikat o błędzie. I nie rozumiem tego drugiego warunku "Nieprawda, że znak", jak znak może przyjąć np. 0? Wtedy kiedy jest zerem? Jeżeli tak to nie wiem po co tu to jest.

1

Zawsze możesz napisać taką jak niżej funkcję lub podobną a potem używać ją wielokrotnie:

#include <stdio.h>
#include <string.h>

int readline(const char *msg,char *buff,unsigned len,unsigned min)
  {
   char ch,*ptr;
   if(min>len-2) min=len-2;
   for(;;)
     {
      printf("%s: ",msg);
      if(fgets(buff,len,stdin))
        {
         ptr=strchr(buff,'\n');
         if(ptr) // wczytano cały wiersz
           {
            *ptr=0;
            if(strlen(buff)>=min) return 1;
            printf("minimalna dlugosc: %d\n\n",min);
           }
         else // użytkownik wprowadził więcej niż len-2 znaki w wierszu
           {
            while((ch=getchar())!='\n');
            printf("zbyt dlugi wiersz\n\n");
           }
        }
      else
        {
         *buff=0; // skonczył się strumień przekierowania
         return 0; // nic nie ma w strumieniu
        }
     }
  }

int main()
  {
   char imie[26],pesel[13];
   if(!readline("Podaj imie",imie,sizeof(imie),1)) return 1;
   printf("podano imie <%s>\n",imie);
   if(!readline("Podaj pesel",pesel,sizeof(pesel),11)) return 1;
   printf("podano pesel <%s>\n",pesel);
   fflush(stdin);
   getchar();
   return 0;
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1