sizeof()在c中返回奇怪的值

时间:2014-05-06 23:30:06

标签: c sockets

大家好我为分配实现了一个多协议服务器,问题是当我使用一个函数(与TCP一起工作得非常好)和UDP时,它会返回一些奇怪的sizeof(rslt)值 这是打印sizeof(rslt)的结果,

  

2272472973019473502357487097781357455774685576584249980024419065361191280234526275581100971853876242196396379418048822289326449959566391370258576510462533256334452274495050078923880161523322073574565992820297844415948337749641827065359769538436094324394016518803754838427202039254842330135966898667440181416654588686493175701171046759340209678542644798608214126898620261227036196985617864721898152919768989286234621310882472277578077210724037954593348269148476835319682392369405001998132692888272764779291883841036795450173075483486283316456690985689093706570659715313373418416626032785942216737626420701207457060042692034113809058230242645165284602182668910345057412276106351085668501025471942442344915958025484738205854146122217473526142186017692920701058864986750388007266706549779899075196338201185437947481794203307088943805129359229291979011929586850204537014834772436384414446076445840451035668547324720434371828348370311512769864669240050561072731126155761543055808184568318969867074799216 6680485067697800917513948201160087224778169619815136033744442198626716251880974996227954137329014095866725172578707717742191749103218728287140600968218667602161628066930470397668362633753341346475937977497019390734734422434964612691048465226365258286142953762247006095000189843305617838473779018503472705410065540807850165010041965346091461331200332511451497690497790367378543486551924221893292784672474993291468062307823045947339072163157187935702819262079978067024962840489044462508137245903235113944234919302323164895317889239321522586956048738773444760769898764375958191713064796780501767777186056598345586828509196381655453913350900498976744116760702779225404253638147784475303924484839145232513088615450662937301515902841074047727047768164109004572062666881745005127128664392023513988846028867443857617835506617248484362040699030566486335234851917802753210578558886946410365517964127167276232990925228582906045900991076852965855040670016037699456645624701071748370395336652735826304864080488960 0709363152032432252410085951706712799052430344895928694442582957645431633369053034305667463823090663464760738164090556152525774466164744037686011101663800170078366921209056500303914474056087892235358298164024357215391588641194707115978140407226154118906542449763834465166058632126443504894420499741513006310822583552919768761548462977412311647236868595822220663005491511561850746178480104681354464439867884163742890098946294243688211351484163203709554184403155848611709506733882593468169901350306884677995915932010321114285505973740406847370286120635158347518247510277661323300043873047950392164942431645418302947950413506210734540437852746639625375347610012995678139901099918378380261823821336209645745980214130228811271994044550978448678801380815142903470540468943168894917972070887965091844883478597646129241181927386702586436228869778709864490945388199788157229336144495868928370130428522581684988316175567123887288601709737949842018996477785851910159268866322819839489792236073965243444078966709 3624907437541226941591245240520207924844128128689438000349924777668111471837242091354159876382021580285379055144718999771005721982983040428783187294609501155912764173768110035459865747935310753231316846263813392915098534543581632657148613313847771071945323639593164682251934093473442545195777200094227132896445437604026121219696929191697809114520884878334125905900512421291098451577200081936661332535029167862238105207037779640033290580769523854129888509506515360662130224968227136008058671505279388721663085953930853769866032069329590096954491495015630933753747808211859974560578358111052927752530637720023827194678573934473710792224546360846934854848774794845984636928997991447694646355496557324158438719071147050424155219037044882503261933744024145388096967434144945092298185160371896905205​​55940494775487076957344200010781415703176415728240860895233439634632912797526990278731739984780391745714390037327203315505427496375837124960562284419088384.000000

服务器

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netinet/tcp.h>
#include <errno.h>

#define MAXLINE 100


struct equation {
    float a;
    char c;
    float b;
};

struct result {
    long double res;
};

int MAX (int a,int b){
    if (a>b) return a;
    return b;
}


int readn(int fd, void *vptr, size_t n)
{
    size_t  nleft;
    ssize_t nread;
    char   *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nread = read(fd, ptr, nleft)) < 0) {
            if (errno == EINTR)
                nread = 0;      /* and call read() again */
            else
                return (-1);
        } else if (nread == 0)
            break;              /* EOF */

        nleft -= nread;
        ptr += nread;
    }
    return (n - nleft);         /* return >= 0 */
}


int writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;
    printf ("\nI'm In %Lf\n",n);
    ptr = vptr;
    nleft = n;
    printf ("%Lf NNNNN  %Lf SIZE %Lf \n",nleft,n,sizeof(*vptr));
    while (nleft > 0) {
        printf ("%Lf\n",nleft);
        fflush (stdout);
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;   /* and call write() again */
            else
                return (-1);    /* error */
        }

        nleft -= nwritten;
        ptr += nwritten;
    }
    printf ("\n 5alawees \n");
// printf ("\n%s\n",vptr);
//    ffulsh (stdout);
    return (n);
}

void HandleClient(int comm_fd);
void Die (const char * msg)
{
    perror(msg);
    exit(1);
}

int passiveUDP (short port){
    struct sockaddr_in servaddr;
    int listen_fd;
    if ((listen_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        Die("Falied to create socket");
    };

    //printf ("%d" ,listen_fd);
    memset( &servaddr,0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(port);

    if (bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
    {
        Die("Failed to bind socket to address");
    }
    return listen_fd;
}

int passiveTCP (short port){
    struct sockaddr_in servaddr;
    int listen_fd;
    if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        Die("Falied to create socket");
    };

    memset( &servaddr,0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htons(INADDR_ANY);
    servaddr.sin_port = htons(port);

    if (bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
    {
        Die("Failed to bind socket to address");
    }

    if (listen(listen_fd, 10) < 0)
    {
        Die("Failed to listen on server socket");
    }
    return listen_fd;
}

int main(int argc, char * argv[])
{
    if (argc != 2) {
        fprintf(stderr, "USAGE: ./HelloITServer <port>\n");
        exit(1);
    }
    char str[100];
    int listen_fd, comm_fd;
    int    usock = passiveUDP (atoi (argv[1]));               /* UDP socket  */

    int    tsock = passiveTCP (atoi (argv[1]));           /* TCP master socket  */
    int    nfds;
    fd_set rfds;                 /* readable file descriptors */
    struct sockaddr_in fsin;     /* the request from address */

    nfds = MAX(tsock, usock) + 1;
    FD_ZERO(&rfds);
    while (1) {
        FD_SET(tsock, &rfds);
        FD_SET(usock, &rfds);
        printf ("HELLO");
        if(select(nfds, &rfds, NULL, NULL, NULL) < 0){
            printf("select error: %d \n",errno);
            exit (1);
        }
        if(FD_ISSET(tsock, &rfds))
        {
            /* TCP slave socket */
            printf ("Hello TCP");
            int ssock;
            //int alen = sizeof(fsin);
            ssock = accept(tsock, (struct sockaddr *) NULL, NULL);
            if(ssock < 0)
                Die("accept failed: jkjkjkjkjkj \n");
            HandleClient (ssock);
            close (ssock);
        }
        if(FD_ISSET(usock, &rfds))
        {
            printf ("Hello UDP");
            HandleClient (usock);
        }
    }

}
void HandleClient(int comm_fd)
{
    struct equation eq;
    struct result rslt;
    bzero (&eq,sizeof (eq));
    bzero (&rslt, sizeof (rslt));
    if ((readn (comm_fd, &eq, sizeof(eq))) == 0){
        Die("Failed to receive from client");
    }
    printf ("\n%Lf  %Lf\n",sizeof (struct result),sizeof (rslt));
    printf ("reciveed %f %c %f",eq.a,eq.c,eq.b);
    switch (eq.c) {
        case '+':
            rslt.res = eq.a+eq.b;
            break;
        case '-':
            rslt.res = eq.a-eq.b;
            break;
        case '*':
            rslt.res = eq.a*eq.b;
            break;
        case '/':
            rslt.res = eq.a/eq.b;
            break;
        case '%':
            rslt.res = (int)eq.a% (int)eq.b;
            break;
        default:
            break;
    }
    printf ("\n%Lf\n",sizeof(rslt));
    printf ("\n%Lf\n",sizeof(rslt));
    printf ("\n%Lf\n",sizeof(rslt));

    writen (comm_fd, &rslt, sizeof (rslt));
    //close (comm_fd);
}

客户(以防万一你需要它)

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<unistd.h>
#include <float.h>
#include <errno.h>

struct equation {
    float a;
    char c;
    float b;
};

struct result {
    long double res;
};

int readn(int fd, void *vptr, size_t n)
{
    size_t  nleft;
    ssize_t nread;
    char   *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nread = read(fd, ptr, nleft)) < 0) {
            if (errno == EINTR)
                nread = 0;      /* and call read() again */
            else
                return (-1);
        } else if (nread == 0)
            break;              /* EOF */

        nleft -= nread;
        ptr += nread;
    }
    return (n - nleft);         /* return >= 0 */
}

int writen(int fd, const void *vptr, size_t n)
{
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;   /* and call write() again */
            else
                return (-1);    /* error */
        }

        nleft -= nwritten;
        ptr += nwritten;
    }
    return (n);
}

int main(int argc,char *argv[])
{
    int sockfd,n;
    char sendline[100];
    char recvline[100];
    struct sockaddr_in servaddr;
    if (argc != 3) {
        fprintf(stderr, "USAGE: ./HelloClient <server_ip> <port>\n");
        exit(1);
    }

    sockfd=socket(AF_INET,SOCK_DGRAM,0);
    bzero(&servaddr,sizeof servaddr);

    servaddr.sin_family=AF_INET;
    servaddr.sin_port= htons(atoi(argv[2]));

    inet_pton(AF_INET,argv[1],&(servaddr.sin_addr));

    connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    struct result rslt;
    struct equation eq;
    //while(1)
    //{
    printf ("Accepted values by the program, from %f to %f\n", FLT_MIN, FLT_MAX);
    printf ("\n possible operations are addition, substraction, division, multiplication and modulo with operators : +,-,*,/,% respectivly\n");
    printf ("\nPlease enter the equation in this form only : \"5.0 + 2.0\" with a single space\n");
    scanf ("%f %c %f", &eq.a,&eq.c,&eq.b);
    if (eq.c!='+' && eq.c!='-' && eq.c!='*' && eq.c!='/' && eq.c!='%'){
        printf ("\n possible operations are addition, substraction, division, multiplication and modulo with operators : +,-,*,/,% respectivly\n");
        exit (1);
    }
    if (eq.c== '%'){
        if (!(eq.a == (float) ((int) eq.a) && eq.b == (float) ((int) eq.b))){
            printf ("Only integer values are accepted with the % operation, please rerun the program\n");
            exit (1);
        }
    }
    //bzero( &eq, sizeof(eq));
    bzero( &rslt, sizeof(rslt) );
    //fgets(sendline,100,stdin); /*stdin = 0 , for standard input */
    writen (sockfd, &eq, sizeof(eq));

    readn (sockfd, &rslt, sizeof(rslt));
    printf("%Lf\n thank you for using this marvelous calculator!\n",rslt.res);
    bzero( &eq, sizeof(eq));
    exit (1);
    //}
}

2 个答案:

答案 0 :(得分:8)

sizeof()返回未指定类型的无符号整数值。

格式规范%Lf需要long double参数。

尝试:

printf ("\n%u\n",(unsigned int) sizeof(rslt));

或者,如果您要打印rslt内容

printf ("\n%Lf\n",rslt.res);

请注意,当我使用gcc 4.6.3编译printf("%Lf\n", sizeof(rslt));等代码时,我会收到以下警告(请注意,-Wall没有增强警告等选项必要的话):

so-test.c:13:33: warning: format ‘%Lf’ expects argument of type ‘long double’, but argument 2 has type ‘long unsigned int’ [-Wformat]

并非所有编译器都如此有用,但如果您使用GCC,则应注意警告。

答案 1 :(得分:6)

问题代码中有几个地方试图将sizeof()的结果'printf()'作为'long double'值:

printf ("\n%Lf  %Lf\n",sizeof (struct result),sizeof (rslt));
...
printf ("\n%Lf\n",sizeof(rslt));
printf ("\n%Lf\n",sizeof(rslt));
printf ("\n%Lf\n",sizeof(rslt));

使用“%zu”打印'sizeof()'返回的'size_t'值,而不是使用'%Lf'。

(使用“%zd”打印'ssize_t'值)