strncmp 并通过传递数组的第 i 个索引地址来比较数组的一部分

Ale*_*lex 1 c

我有这个功能

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");

}
Run Code Online (Sandbox Code Playgroud)

arr 是从另一个函数传递的,它包含 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
Run Code Online (Sandbox Code Playgroud)

所以我喜欢提取这一行,add?title=samsung&price=22000 HTTP/1.1因为这就是函数save_ad。但问题是我无法理解为什么我无法通过arr像这样传递数组第 i 个索引的地址来进行比较

    if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
Run Code Online (Sandbox Code Playgroud)

在索引 4 处,单词title开始,但我无法使用strncmp函数来比较它。在索引 4 处,如果两个字符串相等,则返回 19,该值不是 0

这是我的调用函数

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;

}
Run Code Online (Sandbox Code Playgroud)

如果我arr在 save_ad 函数中 printf 或在 gdb 中查看,它仍然打印包含以下内容的 arr

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
Run Code Online (Sandbox Code Playgroud)

这是完整的代码

// 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);  
       
}
Run Code Online (Sandbox Code Playgroud)

438*_*427 5

改变

if(strncmp((char*)&arr[i],"title=",sizeof("title="))==0)
Run Code Online (Sandbox Code Playgroud)

if(strncmp((char*)&arr[i],"title=",strlen("title="))==0)
Run Code Online (Sandbox Code Playgroud)

将为sizeof您提供 7,因为终止零包含在大小中。因此,当您使用时,sizeof您会比较太多的字符。

使用strlen会给你 6 这就是你想要的。

顺便说一句:不需要演员阵容。&arr[i]已经是一个char*

简单的例子:

    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");
    }
Run Code Online (Sandbox Code Playgroud)

输出:

no match with sizeof
match with strlen
Run Code Online (Sandbox Code Playgroud)