簡體   English   中英

是否可以使用for循環索引訪問結構的元素?

[英]Is it possible to access elements of structure using for loop indexing?

我試圖通過用戶輸入來形成一個IP數據包。 我只做到L4。 l7標頭,包括我作為字符串的數據。 對於L4標頭,用戶必須提供l4不同字段的值,我嘗試將它們轉換為字符串並追加到數據包。 我也想為第3層做類似的事情。

它的工作正常,但在代碼中,我最終為L4的不同領域編寫了類似的代碼。 我在代碼塊中提到了它們。 可以使用for循環將所有4個塊轉換為單個塊。

代碼部分是:

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

typedef struct l4{
    unsigned short source_port;
    unsigned short dest_port;
    unsigned int length;
    unsigned short checksum;
}l4_struct;

void append_l7(char *packet , FILE *fp) {
    char l7_packet[255];
    fscanf(fp , "%[^\n]%*c" , l7_packet);
    strcpy(packet , l7_packet);
}

void append_l4(char *packet , FILE *fp) {
    char l4_header_string[255] , buf[255];
    memset(buf  , 0 ,  255);
    l4_struct l4_header;

//block 1
    fscanf(fp , "%hd" , &l4_header.source_port);
    sprintf(buf , "%x" , l4_header.source_port);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 2
    fscanf(fp , "%hd" , &l4_header.dest_port);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.dest_port);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 3
    fscanf(fp , "%d" , &l4_header.length);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.length);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//block 4
    fscanf(fp , "%hd" , &l4_header.checksum);
    sprintf(buf , "%s %.4x" , l4_header_string , l4_header.checksum);
    strcpy(l4_header_string , buf);
    memset(buf  , 0 ,  255);

//    strcat(l4_header_string , packet);
    sprintf(buf , "%s %s" , l4_header_string , packet);
    strcpy(packet , buf);
}

void append_l3(char *packet , FILE *fp) {

}

int main() {
    FILE *fp = fopen("input_packet.txt" , "r");
    int packet_size = 255; //We can take from user also
    char *packet = (char *)calloc(packet_size , sizeof(char));

    append_l7(packet  , fp);
    append_l4(packet , fp);
//    append_l3(packet , fp);

    //printing packet
    printf("\nPacket:%s\n" , packet);
//    printf("%hd\n%d\n" , sizeof(unsigned short) , sizeof(unsigned int));
    free(fp);
    free(packet);
}

而input_packet.txt是

ab c9 01 00 00 01 00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e 02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01 00 01
58759
53
48
58144

輸出:

Packet:e587 0035 0030 e320 ab c9 01 00 00 01 00 00 00 00 00 00 09 6d 63 63 6c 65 6c 6c 61 6e 02 63 73 05 6d 69 61 6d 69 03 65 64 75 00 00 01 00 01

我想要append_l4( )函數如下所示:

char **dptr = (char **) malloc(sizeof(char *) * 4);
dptr[0] = "source_port";
dptr[1] = "dest_port";
dptr[2] = "length";
dptr[3] = "checksum";

void append_l4(char *packet , FILE *fp) {
    char l4_header_string[255] , buf[255];
    memset(buf  , 0 ,  255);
    l4_struct l4_header;

    for(i = 0; i < 4; i++){
        fscanf(fp , "%(this type varies)" , &l4_header.dptr[i]);
        sprintf(buf , "%s %.4x" , l4_header_string , l4_header.dptr[i]);
        strcpy(l4_header_string , buf);
        memset(buf  , 0 ,  255);
    }

//    strcat(l4_header_string , packet);
    sprintf(buf , "%s %s" , l4_header_string , packet);
    strcpy(packet , buf);
}

可能嗎? 如果是,請建議我該如何實現。

在C ++中迭代一個結構是相似的,但是在C ++中。

我的建議是嘗試使用union ,這將允許您將“不同”的數據類型存儲在同一內存位置。 但是,對於所有可能的field大小(這似乎是您想要的),您必須平等地處理輸入數據。 我自己完成了構建TCP數據包的工作,以下結構非常有用(特別是用於復制操作)。

union packet_u
{
  uint8_t a[__TOTAL_STRUCT_SIZE__];
  struct
  {
      uint16_t field1;
      uint16_t field2;
      uint32_t field3;
      uint16_t field4;
  }
};

讀取輸入文件並將其保存在您的結構中應該很簡單,所以我將讓您繼續研究這個想法。 另外,您可以更改要迭代的最小大小(即uint8_t a[...] )。

snprintf + memcpy + memset(...,0,...)只是胡說八道。 創建一個緩沖區,讀取該緩沖區,然后從該緩沖區復制到另一個緩沖區,然后將該緩沖區歸零...為什么不一直復制到目標緩沖區? snprintf返回寫入的字符數,您可以通過操縱其第一個參數的位置來連接其輸出:

size_t pos = 0;

pos += sprintf(&l4_header_string[pos], "%x", l4_header.source_port);
pos += sprintf(&l4_header_string[pos], " %.4x", l4_header.<next field>);
pos += sprintf(&l4_header_string[pos], " %.4x", l4_header.<next field>);
pos += sprintf(&l4_header_string[pos], " %.4x", l4_header.<next field>);

無論如何,您只能執行一個scanf和一個snprintf:

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

typedef struct l4{
    unsigned short source_port;
    unsigned short dest_port;
    unsigned int length;
    unsigned short checksum;
}l4_struct;

void append_l7(char *packet , FILE *fp) {
    fgets(packet, 255, fp);
}

void append_l4(char *packet , FILE *fp) {
    l4_struct l4_header;

    fscanf(fp , "%hd %hd %d %hd" , 
        &l4_header.source_port,
        &l4_header.dest_port,
        &l4_header.length,
        &l4_header.checksum);
    // we can't snprintf(buffer, "%s", buffer) so we need to create a packet copy
    char *packetcopy = strdup(packet);
    assert(packetcopy != NULL);
    sprintf(packet, "%x %.4x %.4x %.4x %s",
        l4_header.source_port, 
        l4_header.dest_port,
        l4_header.length, 
        l4_header.checksum,
        packetcopy);
    free(packetcopy);
}

int main() {
    FILE *fp = fopen("input_packet.txt" , "r");
    int packet_size = 255; //We can take from user also
    char *packet = (char *)calloc(packet_size , sizeof(char));

    append_l7(packet, fp);
    append_l4(packet, fp);

    printf("Packet:%s\n" , packet);

    // free(fp); ????????
    fclose(fp);
    free(packet);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM