Avatar billede nomak Nybegynder
23. april 2003 - 09:36 Der er 24 kommentarer og
2 løsninger

structs i C

Har søgt lidt på eksperten og er kommet frem til flg.

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

typedef struct {
    int fd;
    char nick;
    char buffer;
} users;

int main(void) {
    users user;
        int new_fd = 4;
    user[new_fd].fd = new_fd;
    user[4].nick = "nomak";
    user[4].buffer = "Hejsa! :)";
}

det jeg skal bruge det til er et brugersystem af en slags..

Håber at i kan se meningen med det, for det er lidt svært for mig at forklare..
Avatar billede nomak Nybegynder
23. april 2003 - 09:38 #1
altså, det skulle kunne være flere end en bruger.. f.eks user[4] og user[5] osv? forstår i?
Avatar billede soreno Praktikant
23. april 2003 - 09:49 #2
#include <stdio.h>
#include <string.h>

typedef struct {
    int fd;
    char *nick;
    char *buffer;
} users;

int main(void) {
    users user[16]; //angiver max antal users
    int new_fd = 4;
    user[new_fd].fd = new_fd;
    user[4].nick = "nomak";
    user[4].buffer = "Hejsa! :)";

    printf("user: %i\n\tnick: %s\n\tbuffer: %s\n", user[4].fd, user[4].nick, user[4].buffer);
}

i structen har jeg ændret til en pointer til en char - eller er der jo kun plads til ét tegn.
Avatar billede arne_v Ekspert
23. april 2003 - 09:50 #3
Jeg tror du mener:

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

typedef struct {
    int fd;
    char nick;
    char buffer;
} users;

int main(void) {
    users user[5];
        int new_fd = 4;
    user[new_fd].fd = new_fd;
    strcpy(user[4].nick,"nomak");
    strcpy(user[4].buffer = "Hejsa! :)");
}
Avatar billede arne_v Ekspert
23. april 2003 - 09:51 #4
Altså [5] for at angive 5 brugere of strcpy til at assigne
chars med.
Avatar billede arne_v Ekspert
23. april 2003 - 09:51 #5
Hov jeg glemte: der skal også allokeres plads:

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

typedef struct {
    int fd;
    char nick[17];
    char buffer[81];
} users;

int main(void) {
    users user[5];
        int new_fd = 4;
    user[new_fd].fd = new_fd;
    strcpy(user[4].nick,"nomak");
    strcpy(user[4].buffer = "Hejsa! :)");
}
Avatar billede arne_v Ekspert
23. april 2003 - 09:52 #6
Jeg regner så med max. 16 tegn i nick og max. 80 tegn i buffer.
Avatar billede soreno Praktikant
23. april 2003 - 09:54 #7
users user[16]
Laver et array af users der hedder user hvor der er plads til 16 users - nummereret fra 0 til 15.
Avatar billede nomak Nybegynder
23. april 2003 - 09:55 #8
det ser lovende ud.. kigger lige på det
Avatar billede nomak Nybegynder
23. april 2003 - 10:01 #9
mange tak :) så skal det bare optimeres :)

fordeler points ud over jer begge 2..
Avatar billede nomak Nybegynder
23. april 2003 - 10:18 #10
hov, mangler lige noget.. hvordan tilføjer jeg noget i slutningen af user[4].buffer?

altså hvis
user[4].buffer = "hej";
user[4].buffer (tilføj) " med dig";
Avatar billede soreno Praktikant
23. april 2003 - 10:21 #11
2 måder:
char temp[80];
strcpy(temp, "hej");
strcat(temp, " med dig");
user[4].buffer = temp;

eller (med udgangspunkt i Arnes forslag).
strcpy(user[4].buffer, "Hejsa! :)");
strcat(user[4].buffer, " med dig");
Avatar billede arne_v Ekspert
23. april 2003 - 10:21 #12
strcpy(user[4].buffer,"hej");
strcat(user[4].buffer," med dig");
Avatar billede soreno Praktikant
23. april 2003 - 10:22 #13
Altså du skal belutte om du vil lave løbende allokering af plads til bufferen (mit eks.), eller du vil have faste størrelser (Arnes eks.).

Begge har fordele og ulemper.
Avatar billede soreno Praktikant
23. april 2003 - 10:24 #14
Hvis du benytter faste størrelser skal du være meget opmærksom på buffer overflow. Det sker hvis du f.eks. kopiere en større string til user[x].buffer end der er plads til.
Det er den type fejl som har været skyld i mange sikkerhedshuller.
Avatar billede nomak Nybegynder
23. april 2003 - 10:48 #15
okay, jeg har et underligt problem nu..

    strcat(user[i].buffer, buf);
    if (strstr(user[i].buffer, "\n\r")) {
        printf(user[i].buffer);
        sendtoall(&master, user[i].buffer, fdmax, nbytes, i);
        strcpy(user[i].buffer, "");
    }

det sender det rigtige data til clienten, MEN det den udskriver i den printf ser MEGET mystisk ud..

den beholder noget af beskederne hver gang.. :(
Avatar billede nomak Nybegynder
23. april 2003 - 10:53 #16
/auth e3cd99bb61ba1ae6ba7d3d9df632bf50
Huth e3cd99bb61ba1ae6ba7d3d9df632bf50
ejsa! :)
9bb61ba1ae6ba7d3d9df632bf50

sådan ser det ud..

1. besked er /auth blabla
2. besked er Hejsa :)
Avatar billede nomak Nybegynder
23. april 2003 - 10:53 #17
dvs. første besked virker sådan set godt nok
Avatar billede soreno Praktikant
23. april 2003 - 10:56 #18
printf(user[i].buffer);
skal være:
printf("%s", user[i].buffer);

Kig evt. formaterings muligheder her:
http://www.cplusplus.com/ref/cstdio/printf.html
Avatar billede nomak Nybegynder
23. april 2003 - 10:59 #19
stadig det samme :/ men ja
Avatar billede arne_v Ekspert
23. april 2003 - 11:07 #20
Brug af "%s" burde fixe det.

Prøv evt. at poste lidt mere kode.

Der må være noget andet galt i logikken.
Avatar billede nomak Nybegynder
23. april 2003 - 11:13 #21
#define PORT 2511

typedef struct {
    int fd;
    char nick[33];
    char buffer[4096];
} users;

int main(void) {

    users user[500];

    fd_set master;

    fd_set read_fds;

    struct sockaddr_in myaddr;

    struct sockaddr_in remoteaddr;

    int fdmax, listener, newfd, nbytes, yes=1, addrlen, i, j;

    char buf[255];

    FD_ZERO(&master);
    FD_ZERO(&read_fds);

    if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        exit(0);
    }

    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(PORT);
    memset(&(myaddr.sin_zero), '\0',8);

    if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(listener, 50) == -1) {
        perror("listen");
        exit(1);
    }

    FD_SET(listener, &master);

    fdmax = listener;

    user[listener].fd = listener;
    strcpy(user[listener].nick, "lytter");
    strcpy(user[listener].buffer, "");

    for(;;) {
        read_fds = master;

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

        for (i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) {
                if (i == listener) {

                    //New connections
                    addrlen = sizeof(remoteaddr);
                    if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
                        perror("accept");
                        exit(1);
                    }

                    else {
                        FD_SET(newfd, &master); //Add to online users!
                        user[newfd].fd = newfd;

                        if (newfd > fdmax) {
                            fdmax = newfd;
                        }
                       
                        printf("Oprettet forbindelse på %d\n", user[newfd].fd);
                    }
                }
                else {
                    //Data from client
                    if ((nbytes = recv(i, buf, sizeof(buf), 0)) <=0) {

                        if (nbytes == 0) {
                            printf("%d lukkede forbindelsen", i);
                        }
                        else {
                            perror("recv");
                        }
                        close(i); //Log out
                        FD_CLR(i, &master); //Remove from master set
                    }
                    else {
                        strcat(user[i].buffer, buf);
                        if (strstr(user[i].buffer, "\n\r")) {
                            printf("%s", user[i].buffer);
                            sendtoall(&master, user[i].buffer, fdmax, nbytes, i);
                            strcpy(user[i].buffer, "");
                        }

                    }
                }
            }
        }
    }

    return 0;
}

int sendtoall(fd_set *master, char buf[255], int fdmax, int nbytes, int id) {
    int j, n;

    for (j = 4; j <= fdmax; j++) {
        if (FD_ISSET(j, master)) {
            if (send(j, buf, nbytes, 0) == -1) {
                perror("send");
            }
        }
    }

    strcpy(buf, "");

    return 1;
}

som i kan se, er den bygget på beejs guide..
Avatar billede nomak Nybegynder
23. april 2003 - 11:16 #22
er villig til at give flere points hvis det er :)
Avatar billede arne_v Ekspert
23. april 2003 - 11:20 #23
Det er dæleme svært at overskue.

Jeg vil ihverfald foreslå en vigtig ændring:

{
                    //Data from client
                    if ((nbytes = recv(i, buf, sizeof(buf), 0)) <=0) {

                        if (nbytes == 0) {
                            printf("%d lukkede forbindelsen", i);
                        }
                        else {
                            perror("recv");
                        }
                        close(i); //Log out
                        FD_CLR(i, &master); //Remove from master set
                    }
                    else {
                        buf[nbytes] = '\0'; /* <------------------- */
                        strcat(user[i].buffer, buf);
                        if (strstr(user[i].buffer, "\n\r")) {
                            printf("%s", user[i].buffer);
                            sendtoall(&master, user[i].buffer, fdmax, nbytes, i);
                            strcpy(user[i].buffer, "");
                        }
Avatar billede nomak Nybegynder
23. april 2003 - 11:26 #24
det var lige hvad der manglede.. mange tak igen :) *kyyyys*

vil du have flere points? 30? :)
Avatar billede arne_v Ekspert
23. april 2003 - 11:28 #25
Hvis du vil kysse, så håber jeg du er en velskabt hun-køn !

:-)

Point er altid velkomne.
Avatar billede nomak Nybegynder
23. april 2003 - 11:47 #26
Næh, er bare lidt gay *G* ej.. er bare glad :)
tak :)
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