[C] "vycistenie" vstupu

Sekcia: Programovanie 18.08.2012 | 22:53
Erik   Návštevník
Zdravim, idem hned k veci:
int x;
char c,*z,*retazec;

scanf("%d",&x);      //1

while( (c = getchar()) != '\n' )  //2
{
	strcat(retazec,z);	
}

Problem: program berie iba prvy input. K druhemu ma nepusti. Predpokladam, ze ked som potvrdil prvy input enterom, co je klavesa ukoncujuca nasledujuci cyklus, program to berie ako aj ukoncenie while-loopu. Aj ked neviem kvoli comu? = prva otazka.

Ako vycistim vstup pred zaciatkom loopu?

Dakujem.

PS: Ked to prehodim, tak to funguje, no take riesenie ma nezaujima.
int x;
char c,*z,*retazec;


while( (c = getchar()) != '\n' )  //1
{
	strcat(retazec,z);	
}

scanf("%d",&x);      //2

    • Re: [C] "vycistenie" vstupu 18.08.2012 | 23:11
      Avatar m4jkl   Používateľ
      ahoj,

      je to jednoduche. ty ked cakas na vstup od uzivatela a zadas na klavesnici napr. 2<ENTER>, tak je v stdin ulozene to cislo 2 a ten enter, cize vlastne '\n'.

      cislo sa ti ulozi do premennej x. potom je tam ten getchar(). ten sa pozrie na stdin a zisti, ze tam nieco je (to je ten enter), takze sa netreba pytat nic uzivatela. kedze '\n' == '\n', tak cyklus okamzite skonci, nevykona sa ani raz.

      vstup vycistis napr. takto:
      while ((c = getchar()) != '\n' && c != EOF);

      btw. premenna 'retazec' nema alokovane ziadne miesto
      • Re: [C] "vycistenie" vstupu 18.08.2012 | 23:23
        Erik   Návštevník
        Aha, dakujem.

        .. alokovane to mam, len som zmazal cast kodu, aby nebol zbytocne bordel :)
      • Re: [C] "vycistenie" vstupu 19.08.2012 | 00:27
        Erik   Návštevník
        #include <stdio.h>
        
        int main(){
        
        char c;
        
        c = getchar();
        printf("1 vstup");
        
        while ((c=getchar())!='\n' && c!=EOF)
        {
        	printf("\n2 vstup\n");
        }
        
        return 1;
        }
        

        Moment. Toto riesenie nefunguje. Mozes to prosim skusit vycistit na tomto konkretnom priklade?
        • Re: [C] "vycistenie" vstupu 19.08.2012 | 13:27
          Avatar m4jkl   Používateľ
          getchar() vracia int, nie char.


          #include <stdio.h>

          int main(){

          char c;

          c = getchar();
          printf("1 vstup\n");

          while ((c=getchar())!='\n' && c!=EOF);

          while ((c=getchar())!='\n' && c!=EOF)
          {
          printf("\n2 vstup\n");
          }

          return 1;
          }
    • Re: [C] "vycistenie" vstupu 20.08.2012 | 08:16
      Avatar ferri Fedora  Používateľ
      Na načítanie celého reťazca zo vstupu slúži funkcia gets().
      Funkcia getchar() je na vstup jedného znaku a jej použitie je v tomto prípade nelogické.

      Na vyčistenie vstupu sa používa konštrukcia
      while(getchar() != '\n')
      ;
      • Re: [C] "vycistenie" vstupu 20.08.2012 | 09:10
        Avatar Fridolín Pokorný Fedora 21  Používateľ
        U funkcii gets() hrozi velmi lahko pretecenie. Urcite je lepsie pouzivat fgets().
        Pouzitie getchar() vs fgets() je otazkou niekde inde. Zalezi, co chce programator urobit. Naviac toto bol len vysek programu s problemom, ktory zakladatel temy riesil.
        Riesenie, ktore bolo vyssie poukazane je lepsie, nakolko zohladnuje aj EOF.
        • Re: [C] "vycistenie" vstupu 20.08.2012 | 10:27
          Avatar ferri Fedora  Používateľ
          Dotaz.
          Ako sa pri zadávaní znakov z klávesnice objaví EOF?
          • Re: [C] "vycistenie" vstupu 20.08.2012 | 11:25
            Avatar m4jkl   Používateľ
            ctrl+d

            ./program < vstup
            • Re: [C] "vycistenie" vstupu 20.08.2012 | 11:49
              Avatar ferri Fedora  Používateľ
              vstup je predpokladám nejaký vstupný súbor.
              • Re: [C] "vycistenie" vstupu 20.08.2012 | 12:11
                Avatar m4jkl   Používateľ
                presne tak
                • Re: [C] "vycistenie" vstupu 20.08.2012 | 12:41
                  Avatar ferri Fedora  Používateľ
                  To je v poriadku. Každý súbor by mal byť ukončený.
                  Ale moja otázka sa týkala len čisto reálneho vstupu klávesnice, kedy chcem vyčistiť všetky zadané znaky po stlačenie <enter>, kvôli novému zadávaniu.
                  Tam mi testovanie na EOF pripadá zbytočné.
                  • Re: [C] "vycistenie" vstupu 20.08.2012 | 13:08
                    Avatar Fridolín Pokorný Fedora 21  Používateľ
                    Uz bolo spominane ctrl+d.
                    Usetrit cca 10 znakov v zdrojovom kode kvoli lenivosti a "snad to nejak pojde" sa obvykle nevyplaca. Skus si pozriet ako su pisane unixove nastroje. Povodna myslienka Unixu (ta myslienka existovala skor btw) bola, ze vsetko je subor a vstup z klavesnice je svojim sposobom taktiez subor. Ak programujes v C urcite vies, ze stdin je FILE *:
                    typedef struct _IO_FILE FILE;
                    extern struct _IO_FILE *stdin;          /* Standard input stream.  */
                    
    • Re: [C] "vycistenie" vstupu 23.08.2012 | 13:55
      ek   Návštevník
      este mam otazku. Chcem citat retazec v subore az kym sa nevyskytne ";" a ulozit ho do premennej.
      priklad suboru (chcem nacitat udaj1):
      udaj1; udaj2
      
      Riesim to takto:
      
       	char *udaj1;
      	int ch;
      	void *p_void = &ch;
      	FILE *fr;
      
      		 
      	if ( (fr = fopen("subor.txt","r")) == NULL)
      	{
      		printf(".......file ERROR\n");
      		fclose(fr);
      		exit(1);
      	}
      	 
      	udaj1 = (char*) malloc(30);
      
      	while ( (ch = getc(fr)) != ';' )
      	{
      		*(char*)p_void = (char) ch;
      		strcat(udaj1, p_void);
      	}
      	
      	printf("%s\n",udaj1);
      	 
      	free(udaj1);
      	
      	fclose(fr);
      
      

      Da sa to riesit jednoduchsie? Resp. pomozete mi v tom vychytat muchy ak tam nejake su?
      • Re: [C] "vycistenie" vstupu 23.08.2012 | 22:47
        Avatar ferri Fedora  Používateľ
        Na inšpiráciu.
        char *udaj1;
          int c, i, velkost;
          FILE *fr;
        
          if ( (fr = fopen("subor.txt","r")) == NULL) {
            printf("Cannot open file\n");
            exit(1);
          }
           
          velkost = 30; 
          udaj1 = (char*) malloc(sizeof(char) * velkost);
          
        /* cyklus bezi pokial nenajde hladany znak alebo nenaplni pole */
          for (i = 0; i < velkost - 1; i++) {
            c = getc(fr);
            /* ak sa nasiel hladany znak cyklus konci,
               inak sa aktualny znak prida do pola */
            if (c == ';') {
              udaj1[i] = '\0';
              break;
            }
            else {
              udaj1[i] = c;
              udaj1[i + 1] = '\0';
            }
          }
          
          printf("%s\n",udaj1);
          
          free(udaj1);
          
          if (fclose(fr) == EOF) {
            printf("Cannot close file");
            exit(1);
          }
        
        • Re: [C] "vycistenie" vstupu 24.08.2012 | 10:38
          Avatar Fridolín Pokorný Fedora 21  Používateľ
          Velmi lahko zapisujes tam, kde by si nemal:
          udaj1[i + 1] = '\0';
          • Re: [C] "vycistenie" vstupu 24.08.2012 | 12:20
            Avatar ferri Fedora  Používateľ
            Ten cyklus for má bežať len po velkost - 2, aby mi ostalo miesto na posledný '\0'.
      • Re: [C] "vycistenie" vstupu 24.08.2012 | 10:42
        Avatar Fridolín Pokorný Fedora 21  Používateľ
        1. Mas alokovane pole o velkosti 30 znakov, nikde nekontrolujes, ci si neprekrocil hranicu.
        2. Ta praca so strcat() radsej nie.