sprintf()



  • Gut, zu wissen, danke!
    Und könntest du evtl. noch den Code bewerten?
    Möchte gerne mal wissen, ob ich wie ein blutiger Anfänger, wie ein Anfänger oder wie ein guter Programmierer schreibe... 🙂

    @seppel
    Wenn du willst, kannst du hier deine mail Adresse posten.
    Ich würde dir dann mal einige Funktionen rund um POP3 schicken.

    mfg grottenolm



  • soll keine kritik sein, nur was dich darueber denke:

    #include <stdio.h>
    #include <string.h>
    #include <winsock2.h>
    #include <stdlib.h>
    
    int     StartWSA( void )
    {
        WSADATA wsa;
        return WSAStartup( MAKEWORD( 2 , 0 ) , &wsa );
    }
    //schoen - gut dies in eine funktion zu kapseln
    //uU sollte StartWSA das programm mit einer ordentlichen
    //fehlermeldung beenden wenn WSAStartup fehlschlaegt
    //muss aber nicht sein
    
    int     StartSocket( void )
    {
        int nSocket = 0;
        return nSocket = socket( AF_INET , SOCK_STREAM , 0 );
    }
    //auch schoen gekapselt - nur socket returned (unter Windows)
    //SOCKET und nicht int
    
    void EingabeDaten( char *szUsername , char *szPasswort , char *szPOP , int *nPort )
    {
        fflush( stdin );
        //boese! fflush ist fuer stdin nicht definiert!
        printf("DNS ( zb.: pop3.web.de ): ");
        scanf("%s",szPOP );
        //besser fgets() wegen buffer overflows
        fflush( stdin );
        //boese
        printf("Port ( E-Mail 110 ): ");
        scanf("%i",nPort);
        //ich wuerde auch hier fgets verwenden (und nachdem ich sicher bin
        //dass eine zahl eingegeben wurde, sscanf machen um die zahl auszulesen
        //bzw. ist atoi dann besser...
        fflush( stdin );
        //boese
        printf("Username: ");
        scanf("%s",szUsername );
        //wie gesagt: fgets()
        fflush( stdin );
        //boese
        printf("Passwort: ");
        scanf("%s",szPasswort );
        //wie gesagt: fgets()
    }
    
    int VerbindungAufbauen( char *szUsername , char *szPasswort , int nPort , char *szPOP , int nSocket )
    {//szUsername und szPassowort und szPOP sollten const char* sein
        struct sockaddr_in addr;
        struct  hostent *host = NULL;
        memset( &addr , 0 , sizeof( addr ) );
        addr.sin_port   = htons( (unsigned short)nPort );
        addr.sin_family = AF_INET;
        host = gethostbyname( szPOP );
        addr.sin_addr = *(struct in_addr*)host->h_addr;
        return connect( nSocket , (SOCKADDR*)&addr , sizeof( addr ) );  
    } //ansonsten recht gut
    
    int     main( void )
    {
        int     nSocket         = 0;
        char    szPOP[50]       = { 0 };
        int     nPort           = 0;
        char    szUsername[40]  = { 0 };
        char    szPasswort[40]  = { 0 };
        char    szBuffer[1024]  = { 0 };
        int     nAnzahl = 0;
        if( StartWSA() != 0 )
        {
            fprintf( stderr , "WSAStartup() fehlerhaft...\n");
            return 1; //schoen
        }
        if( ( nSocket = StartSocket() ) == -1 )
        {
            fprintf( stderr , "socket() fehlerhaft...\n");
            return 2;
        }   
        EingabeDaten( szUsername , szPasswort , szPOP , &nPort );
        if( ( VerbindungAufbauen( szUsername , szPasswort , nPort , szPOP, nSocket ) ) == -1 )
        {
            fprintf( stderr , "connect() fehlerhaft...%i\n",WSAGetLastError());
            return 3;
        }
        nAnzahl = recv( nSocket , szBuffer , strlen( szBuffer ) , 0 );
        szBuffer[nAnzahl] = '\0';
        printf("%s\n",szBuffer );
        sprintf( szBuffer , "USER %s\0",szUsername );
        //\0 ist unnoetig
        //besser waere memcpy, da du die groesse von szBuffer kennst
    
        if( !send( nSocket , szBuffer , strlen( szBuffer ) , 0 ) )
            puts("Username nicht versendet");
            //besser eine fehlermeldung: fprintf(stderr
        else
            printf("\nNachricht versenden: %s",szBuffer );
        nAnzahl = recv( nSocket , szBuffer , sizeof( szBuffer ) , 0 );
        szBuffer[nAnzahl] = '\0';
        printf("%s\n",szBuffer );
        sprintf( szBuffer , "PASS %s\0",szPasswort );
        //siehe oben
        if( !send( nSocket , szBuffer , strlen( szBuffer ) , 0 ) )
            puts("Passwort nicht versendet");
            //siehe oben
        else
            printf("\nNachricht versenden: %s",szBuffer );
        nAnzahl = recv( nSocket , szBuffer , sizeof( szBuffer ) , 0 );
        szBuffer[nAnzahl] = '\0';
        printf("%s\n",szBuffer );
    
        WSACleanup();
        closesocket( nSocket );
        return 0;
    }
    


  • Mhhh, sorry...aber du hast ausversehen den Code von seppel rezensiert.
    Meiner ist der GNU/Linux kompatible 🙂

    Danke 😉

    mfg grottenolm

    #include <stdio.h>
    #include <netdb.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #define POP_PORT 110
    #define BUFFSIZE 1500
    
    struct pop_user
    {
        char username[30];
        char passwd[30];
        char dns_addr[20];
    
        int sockfd;
        struct sockaddr_in servaddr;
    
        char buffer[BUFFSIZE];
    
    };
    
    int connect_pop_server(struct pop_user *pop_data);
    int check_messages(struct pop_user *pop_data);
    int registrate(struct pop_user *pop_data);
    int get_answere(struct pop_user *pop_data);
    
    int main(void) 
    {
        struct pop_user pop_data;
    
        /* TESTING!!! */
        strcpy(pop_data.dns_addr,"pop.gmx.de");
        strcpy(pop_data.username,"test@gmx.de");
        strcpy(pop_data.passwd,"test");
    
        connect_pop_server(&pop_data);
        printf("Ok, you are connected :)\n");
    
        registrate(&pop_data);
    
        printf("Messages: %i\n",check_messages(&pop_data));
    
        return 0;
    }
    
    int registrate(struct pop_user *pop_data) 
    {
        /* send the username */
        snprintf(pop_data->buffer,BUFFSIZE,"USER %s\n",pop_data->username);
        if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
            perror("send() failed");
            return 1;
        }
    
        if((get_answere(pop_data)) == -1)
            return  1;
    
        /* send the passwd */
            snprintf(pop_data->buffer,BUFFSIZE,"PASS %s\n",pop_data->passwd);
            if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
                    perror("send() failed");
                    return 1;
            }
            if((get_answere(pop_data))== -1)
            return  1;
    
        return 0;
    }
    
    int connect_pop_server(struct pop_user *pop_data)
    {
        struct hostent *host;
    
        pop_data->servaddr.sin_port = htons(POP_PORT);
        pop_data->servaddr.sin_family = AF_INET;
    
        /* get the IP adress */
        host = gethostbyname(pop_data->dns_addr);
    
        pop_data->servaddr.sin_addr = *(struct in_addr*) host->h_addr;
    
        /* get a socket file deskriptor */
        if((pop_data->sockfd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
            perror("socket() failed");
            return -1;
        }
        /* connect to the server */
        if((connect(pop_data->sockfd, &pop_data->servaddr, sizeof(pop_data->servaddr)))== -1) {
            perror("connect() failed");
            return -1;
        }
    
        /* get the answer from the server */
        if((get_answere(pop_data))== -1)
            return -1;
    
        return 0;
    }
    
    int check_messages(struct pop_user *pop_data)
    {
        int msg = 1; 
    
        while(1) {
            snprintf(pop_data->buffer,BUFFSIZE,"LIST %i\n",msg);
            if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
                perror("send() failed");
                return -1;
            }
    
            if((get_answere(pop_data))== -1)
                break;
    
            msg++;
        }
    
        return msg-1;
    }
    
    int get_answere(struct pop_user *pop_data)
    {
        char buffer[BUFFSIZE];
        int bytes;
    
        bytes = recv(pop_data->sockfd, buffer, sizeof(buffer), 0);
        buffer[bytes] = '\0';
    
        printf("--> %s",buffer);
    
        if(buffer[0] == '-')
            return -1;
    
        return 0;
    }
    


  • @Shade Of Mine, trotzdem vielen dank 🙂

    @grottenolm, du kannst das ganze ja mal an die emailadresse meines großen bruders schicken ( meine hab ich aufgegeben da einfach zuviel sexwerbung ins haus flattert und ich derzeit auf eine neue warte ). email ist strosaenckel@web.de . danke schon mal, tschaui



  • sorry - hab den falschen code erwischt.

    deiner ist besser, gibt eigentlich nix zu beanstanden nur n paar kosmetik sachen:

    #include <stdio.h>
    #include <netdb.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #define POP_PORT 110
    //POP_PORT sollte vielleicht besser ein const int sein
    #define BUFFSIZE 1500
    
    struct pop_user
    {
        char username[30];
        char passwd[30];
        char dns_addr[20];
        int sockfd;
        struct sockaddr_in servaddr;
        char buffer[BUFFSIZE];
    };
    
    int connect_pop_server(struct pop_user *pop_data);
    int check_messages(struct pop_user *pop_data);
    int registrate(struct pop_user *pop_data);
    int get_answere(struct pop_user *pop_data);
    //schoen, das gefaellt mir!
    
    int main(void) 
    {
        struct pop_user pop_data;
    
        strcpy(pop_data.dns_addr,"pop.gmx.de");
        strcpy(pop_data.username,"test@gmx.de");
        strcpy(pop_data.passwd,"test");
        //uU besser eine Funktion die pop_data fuellt
        //damit kannst du besser kapseln
    
        connect_pop_server(&pop_data);
        printf("Ok, you are connected :)\n");
        registrate(&pop_data);
        printf("Messages: %i\n",check_messages(&pop_data));
        return 0;
    }
    int registrate(struct pop_user *pop_data) 
    {
        /* send the username */
        snprintf(pop_data->buffer,BUFFSIZE,"USER %s\n",pop_data->username);
        //vielleicht solltest du checken ob username abgeschnitten wurde
        //(snprintf returned dann -1)
        //vielleicht brauchst du das aber nicht, da Buffer sowieso immer
        //gross genug ist! (sizeof(username) + sizeof("USER \n") < BUFFERSIZE)
        if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
            perror("send() failed");
            return 1;
            //fehlermeldung die in main nicht abgefangen wird - also entwder in main
            //abfangen oder abort() aufrufen
        }
        if((get_answere(pop_data)) == -1)
            return  1; //siehe oben
        /* send the passwd */
            snprintf(pop_data->buffer,BUFFSIZE,"PASS %s\n",pop_data->passwd);
            //siehe oben
            if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
                    perror("send() failed");
                    return 1; //siehe oben
            }
            if((get_answere(pop_data))== -1)
            return  1; //siehe oben
        return 0;
    }
    int connect_pop_server(struct pop_user *pop_data)
    {
        struct hostent *host;
        pop_data->servaddr.sin_port = htons(POP_PORT);
        pop_data->servaddr.sin_family = AF_INET;
        /* get the IP adress */
        host = gethostbyname(pop_data->dns_addr);
        pop_data->servaddr.sin_addr = *(struct in_addr*) host->h_addr;
    
        /* get a socket file deskriptor */
        if((pop_data->sockfd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
            perror("socket() failed");
            return -1; //fehler abfangen oder aborten
        }
        /* connect to the server */
        if((connect(pop_data->sockfd, &pop_data->servaddr, sizeof(pop_data->servaddr)))== -1) {
            perror("connect() failed");
            return -1; //siehe oben
        }
        /* get the answer from the server */
        if((get_answere(pop_data))== -1)
            return -1; //siehe oben
        return 0;
    }
    int check_messages(struct pop_user *pop_data)
    {
        int msg = 1; 
        while(1) {
            snprintf(pop_data->buffer,BUFFSIZE,"LIST %i\n",msg);
            //sprintf tut es auch
            if((send(pop_data->sockfd, pop_data->buffer, strlen(pop_data->buffer), 0))== -1) {
                perror("send() failed");
                return -1; //siehe oben
            }
    
            if((get_answere(pop_data))== -1)
                break;
            msg++;
        }
        return msg-1;
    }
    int get_answere(struct pop_user *pop_data)
    {
        char buffer[BUFFSIZE];
        int bytes;
        bytes = recv(pop_data->sockfd, buffer, sizeof(buffer), 0);
        buffer[bytes] = '\0';
        printf("--> %s",buffer);
        if(buffer[0] == '-')
            return -1;
        return 0;
    }
    

    die Kapselung ist schoen!!



  • Ok, vielen Dank für deine Rezension. 🙂
    Du musst nämlich wissen, dass ich in diesem Gebiet manchmal ein wenig perfektionistisch bin....

    mfg grottenolm



  • hallo,
    hab mir mal diesen interessanten beitrag durchgelsen und hab dazu mal eine kleine frage:

    int VerbindungAufbauen( char *szUsername , char *szPasswort , int nPort , char *szPOP , int nSocket )
    {//szUsername und szPassowort und szPOP sollten const char* sein
    

    warum das const noch zusätzlich dazu ?
    mfg ronny



  • stichwort const-correctness

    das ist in C nicht ganz so wichtig, aber dennoch schadet es nicht (und kann aber helfen)

    wenn eine funktion den Usernamen nicht verändert, dann gibt es 2 möglichkeiten dies zu dokumentieren:

    void nochange(char* username);
    /*username wird nicht verändert*/

    oder
    void nochange(const char* username);

    letzteres verhindert ein unwissentliches ändern von username - gegen ein mutwilliges kann man sich nicht schützen.

    In C ist soetwas leider kein muss 😞 in C++ allerdings schon.



  • in C gibt es keine const-correctness, das Überschreiben auf ein als const deklariertes Objekt führt aber zu undefiniertem Verhalten. const wird lediglich vom Compiler zu Optimierungszwecken verwendet (genau wie restrict und volatile, wobei man bei letzterem vielleicht Pessimierungszwecke sagen sollte ;))



  • ahso, danke euch beiden


Anmelden zum Antworten