Home > Mobile >  strncmp and comparing part of an array by passing i-th index address of an array
strncmp and comparing part of an array by passing i-th index address of an array

Time:09-23

I have this function

void save_ad(int n,char arr[n])
{
    int i=0;
    int price=0;
    char title[100];
    
    printf("entered\n");
    
    while(i<n)
    {
        
            
        if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
        
        {
            
            int x=0;
            while(arr[x]!='\r')
            {
                printf("%c\n",arr[x]);
            }
            printf("\n");
        }
        i  ;
    }
    printf("\n");

}

the arr is passed from another function and it contains this

add?title=samsung&price=22000 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

So I like to extract this line add?title=samsung&price=22000 HTTP/1.1 for this is the function save_ad. but the problem I could not get to understand why I am unable to compare by passing address of i-th index of array arr like this

    if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)

at index 4 the word title begin, but I am unable to compare it using strncmp function. at index 4 it returns 19 which is not 0 if two strings are equal

this is my calling function

int process(int size,char buffer[size],char status)
{
    int i=0;
    int line_len=0;
    char *line=malloc(sizeof(char) *150);

    while(i<size)
    {
        if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
        return 3;

        if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
        {
          
           while(buffer[i]!='\n')
           {
            line[line_len]=buffer[i];
            line_len  ;
            i  ;

           }

           //line[line_len]='\0';
           //printf("%s\n",line);
           memset(line,0,line_len);

           line_len=0;
           return 2; 
        }
        if(strncmp((void*)&buffer[i],"add?",strlen("add?"))==0)
        {
            
            save_ad(size-i,(void*)&buffer[i]);
        
        }
        


        i  ;
        line_len  ;
    }

    return 2;

}

if I printf arr in save_ad function or see in gdb it is still prints arr containing the following

add?title=samsung&price=22000 HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

this is full code

// Server side C/C   program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

//aaa
#define PORT 80
#define BUF_SIZE 20000

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

int min(int a, int b)
{
    return a>b?b:a;
}

void save_ad(int n,char arr[n])
{
    int i=0;
    int price=0;
    char title[100];
    
    printf("entered\n");
    
    while(i<n)
    {
        
            
        if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
        
        {
            printf("cool [[[[[[[");
            int x=0;
            while(arr[x]!='\r')
            {
                printf("%c\n",arr[x]);
            }
            printf("\n");
        }
        i  ;
    }
    printf("\n");

}

int process(int size,char buffer[size],char status)
{
    int i=0;
    int line_len=0;
    char *line=malloc(sizeof(char) *150);

    while(i<size)
    {
        if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
        return 3;

        if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
        {
          
           while(buffer[i]!='\n')
           {
            line[line_len]=buffer[i];
            line_len  ;
            i  ;

           }

           //line[line_len]='\0';
           //printf("%s\n",line);
           memset(line,0,line_len);

           line_len=0;
           return 2; 
        }
        if(strncmp((void*)&buffer[i],"add?",strlen("add?"))==0)
        {
            
            save_ad(size-i,(void*)&buffer[i]);
        
        }
        


        i  ;
        line_len  ;
    }

    return 2;

}
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
    off_t orig;

    if (offset != NULL) {

        /* Save current file offset and set offset to value in '*offset' */

        orig = lseek(in_fd, 0, SEEK_CUR);
       
        if (orig == -1)
            return -1;
        if (lseek(in_fd, *offset, SEEK_SET) == -1)
            return -1;
    }

    size_t totSent = 0;

    while (count > 0) {
        size_t toRead = min(BUF_SIZE, count);

        char buf[BUF_SIZE];
        ssize_t numRead = read(in_fd, buf, toRead);
        if (numRead == -1)
            return -1;
        if (numRead == 0)
            break;                      /* EOF */

        ssize_t numSent = write(out_fd, buf, numRead);
        if (numSent == -1)
            return -1;
        if (numSent == 0)               /* Should never happen */
            printf("fatal: should never happen");
            //fatal("sendfile: write() transferred 0 bytes");

        count -= numSent;
        totSent  = numSent;
    }

    if (offset != NULL) {

        /* Return updated file offset in '*offset', and reset the file offset
           to the value it had when we were called. */

        *offset = lseek(in_fd, 0, SEEK_CUR);
        if (*offset == -1)
            return -1;
        if (lseek(in_fd, orig, SEEK_SET) == -1)
            return -1;
    }

    return totSent;
}


int main(int argc, char const *argv[])
{
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1000] = {0};
    int get_return321;
    //GET /css/style.css HTTP/1.1
    char *hello = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n";
    //"HTTP/1.1 200 OK\\r\\n" \
            "Content-Length: 55\r\n\n Content-Type: application/json\r\n '{\"name\":\"fawad\"}'";
    
    
    //struct stat sb;
    char *hello1 = "HTTP/1.1 200 Okay\r\nContent-Type: text/css\r\n\r\n";
    struct stat sb_html;
    struct stat sb_css;     
    int fd_in_html;//=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
    const char* filename_html="/home/fawad/Desktop/C-work/temp.html";
    
    int fd_in_css;//=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
    const char* filename_css="/home/fawad/Desktop/C-work/css/style9.css";

    
    

    
    //printf("%lu\n",sb_css.st_size);
    

    
            
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        //exit(EXIT_FAILURE);
    }
    
    
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
    {
        perror("setsockopt");
        //exit(EXIT_FAILURE);
    }

       /*if( setsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sb.st_size, sizeof(sb.st_size)))
        {
        printf("sockopt\n");
        }*/
        
        /*int state = 1;
    if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)))
    {
        printf("sockopt\n");
    }*/
    
    int state = 1;
    if(setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)))
    {
        printf("TCP CORK\n");
    }

    

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );
    
    
    if (bind(server_fd, (struct sockaddr *)&address,sizeof(address))<0)
    {
        perror("bind failed");
        //exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        //exit(EXIT_FAILURE);
    }
    
    
    while(1)
    {
        printf("in loop\n");
    
    
    
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                            (socklen_t*)&addrlen))<0)
        {

        //  exit(EXIT_FAILURE);
        }
    
        
    
    
    
             printf("request came\n");
    
    
        valread = read( new_socket , buffer, (1000));


        
        //printf("%s\n",buffer );
        printf("_________________________________\n");
        //printf("%s\n",buffer);
        get_return321=process(900,buffer,'r');
        buffer[499]='\0';
        printf("\n");
        printf("\n");
        
        
        if(get_return321==2)
        {
            
            

            send(new_socket , hello , strlen(hello) , 0 );
            //send(new_socket , buffer_html , sb_html.st_size , 0 );
            fd_in_html=open("/home/fawad/Desktop/C-work/temp.html",O_RDONLY);
            if (stat(filename_html, &sb_html) == -1) 
            {
                printf("%d\n",errno);
                //exit(EXIT_FAILURE);
            }
            sendfile(new_socket,fd_in_html,0,sb_html.st_size);
            close(fd_in_html);
            printf("html sent\n");
            

        }   
        if(get_return321==3)
        {
            send(new_socket , hello1 , sb_css.st_size , 0 );
            fd_in_css=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
            if (stat(filename_css, &sb_css) == -1) 
            {
                printf("%d\n",errno);
                //exit(EXIT_FAILURE);
            }
            sendfile(new_socket,fd_in_css,0,sb_css.st_size);
            printf("3 reached\n");
            close(fd_in_css);
            

        }
        close(new_socket);
        state = 0;
        setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
        //close(new_socket);            
        state = 1;
        setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));



    }
    
    //close(fd_in);
    close(fd_in_html);  
       
}

CodePudding user response:

Change

if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)

to

if(strncmp((char*)&arr[i],"title=",strlen("title="))==0)

The sizeof will give you 7 as the terminating zero is included in the size. So when you use sizeof you compare one too many characters.

Using strlen will give you 6 which is what you want.

BTW: No need for the cast. &arr[i] is already a char*

Simple example:

    char* arr = "add?title=samsung&price=2200";

    // Using sizeof
    if(strncmp(&arr[4],"title=",sizeof("title="))==0)
    {
        puts("match with sizeof");
    }
    else
    {
        puts("no match with sizeof");
    }

    // Using strlen
    if(strncmp(&arr[4],"title=",strlen("title="))==0)
    {
        puts("match with strlen");
    }
    else
    {
        puts("no match with strlen");
    }

Output:

no match with sizeof
match with strlen
  •  Tags:  
  • c
  • Related