Avatar billede nomak Nybegynder
17. juni 2003 - 21:33 Der er 27 kommentarer og
1 løsning

kb_getc funktion driller

jeg har en funktion som ser således ud:

unsigned char kb_getc(void)
{
  unsigned char ch;
  ssize_t size;

  size = read (0, &ch, 1);
  if (size == 0)
  {
    return 0;
  }
  else
  {
    return ch;
  }
}

Og bruger det i min main funktion..:
for(;;) {
....
if(ch = kb_getc())
{
    char a[100];
    sprintf(a,"%c", ch);

    strcat(sayFromConsole, a);

    if(ch == '\n') {

        if(strlen(sayFromConsole) >1) {
            char kb_out[1000];

            replace(sayFromConsole, "\n", "");

            sprintf(kb_out, "none.gif!.!<font color=CCCCCC>Gh0st : %s</font>\n", sayFromConsole);
            sendtoall(kb_out);

            printf("Gh0st : %s\n", sayFromConsole);
            //write_system(sayFromConsole, 1);
                }

        strcpy(sayFromConsole, "");
    }
}
....
}

men jeg har det problem at der går MEGET lang tid fra man har trykket 'enter' til der sker noget..

det er jo ikke meningen, men aner ikk hvad det kan være..

skulle måske nævne at min main funktion er LANG.. har det noget at sige?
Avatar billede nomak Nybegynder
17. juni 2003 - 21:37 #1
glemte også at den for løkke går i stå(pause) hvis man ikke skriver noget i et stykke tid
Avatar billede nomak Nybegynder
17. juni 2003 - 21:44 #2
flg. kode virker som det skal.. kan ikk se nogen forskel i opbygningen..

unsigned char kb_getc(void)
{
  unsigned char ch;
  ssize_t size;

  size = read (0, &ch, 1);
  if (size == 0)
  {
    return 0;
  }
  else
  {
    return ch;
  }
}


int main()
{
    unsigned char ch;

    char say[400];

    for(;;)
    {
        if(ch = kb_getc())
        {
            char a[100];
            sprintf(a,"%c", ch);

            strcat(say, a);

            if(ch == '\n') {

                if(strlen(say) >1) {
                    printf("Output : %s", say);
                }

                strcpy(say, "");
            }
        }

    }
    return 0;
}
Avatar billede arne_v Ekspert
17. juni 2003 - 22:53 #3
Har ikke noget med dit problem at gøre men:

char say[400];
memset(say,'\0',sizeof(say)); // initialisere
int ix = 0; // pointer til hvor langt du er kommet
...
// char a[100];
// sprintf(a,"%c", ch);
// strcat(say, a);
say[ix] = ch;
ix++;
Avatar billede bertelbrander Novice
17. juni 2003 - 22:56 #4
Hvilket OS, hvilken kompiler?
Hvorfor bruger du read til at læse fra stdin?
Avatar billede nomak Nybegynder
17. juni 2003 - 22:57 #5
bertelbrander -> FreeBsd 4.x, cc


hvad skal jeg ellers bruge?
Avatar billede arne_v Ekspert
17. juni 2003 - 22:59 #6
bertel>

Jeg formoder det kbhit/getch funktionalitet han skal bruge.
Avatar billede nomak Nybegynder
17. juni 2003 - 23:07 #7
kode nu...

unsigned char kb_getc(void)
{
  unsigned char ch;
  ssize_t size;

  size = read (0, &ch, 1);
  if (size == 0)
  {
    return 0;
  }
  else
  {
    return ch;
  }
}


int main()
{
    unsigned char ch;

    char say[400];

    int ix = 0;

    memset(say,'\0',sizeof(say)); // initialisere

    for(;;)
    {
        if(ch = kb_getc())
        {
        say[ix] = ch;

        ix++;

            if(ch == '\n') {

                if(strlen(say) >1) {
                    printf("Output : %s", say);
                }
        ix = 0;
                say[0] = '\0';
            }
        }

    }
    return 0;
}

output:

-bash-2.05b$ cc -o a a.c
-bash-2.05b$ ./a
asd<-input
Output : asd
a<-input
Output : a
d <-- hvor kommer den fra!?
Avatar billede arne_v Ekspert
17. juni 2003 - 23:11 #8
say[0] = '\0';

skal nok ændres til:

      memset(say,'\0',sizeof(say));
Avatar billede arne_v Ekspert
17. juni 2003 - 23:12 #9
Og det har som sagt intet med dit oprindelige problem at gøre.

Jeg syntes bare at sprintf var et overkill til problemet at appende
en char.
Avatar billede nomak Nybegynder
17. juni 2003 - 23:12 #10
rigtigt.. hmm, prøver lige at bygge det ind i min kode, og se hvad der sker..
Avatar billede bertelbrander Novice
17. juni 2003 - 23:12 #11
Du skal kalde memset(say,'\0',sizeof(say)); når du har udskrevet (say[0] er ikke nok).
Avatar billede nomak Nybegynder
17. juni 2003 - 23:12 #12
if(ch == '\n') { <-- har på fornemmelsen det er det der er galt??
Avatar billede arne_v Ekspert
17. juni 2003 - 23:15 #13
Ja - umiddelbart ville jeg have troet at du skulle bruge:

if(ch == '\r') {

nede på dette niveauu !
Avatar billede arne_v Ekspert
17. juni 2003 - 23:15 #14
nede på dette niveau = nede på så hardware tæt IO som at læse keystrokes.
Avatar billede nomak Nybegynder
17. juni 2003 - 23:24 #15
har skiftet det ud med \r.. nu gør den bare ingenting

kan det være kjin kb_getc der ikke virker!?
Avatar billede nomak Nybegynder
17. juni 2003 - 23:34 #16
kjin = min.. hehe, tror snart jeg skal have noget søvn.. :)
Avatar billede arne_v Ekspert
18. juni 2003 - 07:46 #17
Tja - alt er muligt.
Avatar billede segmose Nybegynder
18. juni 2003 - 09:59 #18
#define SAYMAX (400)

unsigned char kb_getc(void) {
  unsigned char ch;
  ssize_t size;

  size = read (0, &ch, 1);
  if (size == 0) {
    return 0;
  } else {
    return ch;
  }
}


int main() {
    unsigned char ch;
    char say[SAYMAX];
    int ix = 0;

// unødvendig, se nedenfor    memset(say,'\0', SAYMAX); // initialisere

    for(;;) {
        if(ch = kb_getc()) {
            if(ch == '\n' || ch == '\r') {
                say[ix] = '\0'; // slut streng.
                if(ix > 0) { // was > 1, men jeg tager ikke \n / \r med
                    printf("Output : %s\n", say);
                }
                ix = 0;
                say[0] = '\0';
            } else {
              say[ix++] = ch;
            }
        }
    }
    return 0;
}

Dette ser ud til at virke.

Y:\TEST>kb
abc
Output : abc
123
Output : 123
a
Output : a
Avatar billede nomak Nybegynder
18. juni 2003 - 12:48 #19
Har sat det ind i min kode, men den gør stadig det samme.. det er som om den for løkke går i pause..

Hvis jeg nu bare laver en

if (ch = kg_getc()) {
  //gør nada..
}

så gør den det.. så det må jo være kb_getc der er noget galt med!

det er somom den VENTER på at jeg skal skrive noget?!
Avatar billede nomak Nybegynder
18. juni 2003 - 12:55 #20
man kan vel sige at det "lagger"..

programmet går helt i stå når jeg bare indsætter de 2 linier kode!
Avatar billede segmose Nybegynder
18. juni 2003 - 13:11 #21
Ja, jeg kan nu se problemet, så må du vel også til at bruge select(...), der har en timeout, det lader til at stdin altid venter på enter.
Avatar billede nomak Nybegynder
18. juni 2003 - 13:14 #22
hvordan skal det så kringles? eksempel please :)
Avatar billede nomak Nybegynder
19. juni 2003 - 12:42 #23
for(;;) {
        time_t new_ping;
        read_fds = master;
        new_ping = time(NULL);

        if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
        }

        if((new_ping-ping) >= 15) {
            ping = time(NULL);
            sendtoall("#PING\n");
        }

        if(ch = kb_getc())
        {
            if(ch == '\n' || ch == '\r') {
                sayFromConsole[ix] = '\0';

                if(ix > 0) {
                    //char kb_out[1000];

                    //replace(sayFromConsole, "\n", "");

                    //sprintf(kb_out, "none.gif!.!<font color=CCCCCC>Gh0st : %s</font>\n", sayFromConsole);
                    //sendtoall(kb_out);

                    printf("Gh0st : %s\n", sayFromConsole);
                }

                ix = 0;
                sayFromConsole[0] = '\0';
            } else {
                sayFromConsole[ix++] = ch;
            }
        }

        //mere kode...
    }


ved ikke om det er fordi min select ikke har en timeout?
Avatar billede segmose Nybegynder
19. juni 2003 - 14:53 #24
Det er det nok, en af de sidste argumneter er en timeout jeg kan bare ikke huske om det betyder at du venter for evigt eller ikke venter hvis der ikke er noget.

Du skulle også kunne vente på keyboard i din select, så vidt jeg husker, venter du i forvejen på flere forbindelser? så tilføj fd=0 til dem du venter på.
Avatar billede nomak Nybegynder
19. juni 2003 - 16:07 #25
Det er den sidste det er timeout.. men ved ikke om NULL = vent for evigt?

forstod så ikke lige det sidste!?
Avatar billede segmose Nybegynder
19. juni 2003 - 17:39 #26
Prøv at sætte ventetiden til 0.

Du kan vente på flere forbindelser samtidig, jeg går ud fra at det er noget net du har gang i, du kan så vente på flere filedescriptorer (fd) fx. også på 0 (stdin).

se evt. http://www.ecst.csuchico.edu/~beej/guide/net/html/advanced.html#select
der er et exemple på vent på keyboard og vent på multiple forbindelser/input.
Avatar billede nomak Nybegynder
19. juni 2003 - 18:50 #27
Skal jeg så oprette en ny "readfds" eller kan jeg bruge den jeg har i min anden select?
Avatar billede segmose Nybegynder
20. juni 2003 - 08:27 #28
Du skal tilføje til den der er vel af typen rd_set;

struct timeval tv;

// Vent 2,5 sek.
tv.tv_sec = 2;
tv.tv_usec = 500000;

FD_SET(STDIN, &readfds); // tilføj STDIN til vente set.

select(fdmax+1, &readfds, NULL, NULL, &tv); // fdmax skal være den max fd du venter på.

if (FD_ISSET(STDIN, &readfds))
  printf("A key was pressed!\n"); // do things with keypress.
else
  if (FD_ISSET(EtMedlemAfMaster, &readfds))
    printf("medlem af master master\n"); // behandle anden input
  else
    printf("Timed out.\n"); // intet sket i 2,5 sek, opdater statistik.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester