1

共有メモリへの構造体の書き込みに問題があります。これは、コードが構造体の最初の部分のみを書き込むためです。

これが私のデータ構造です:

struct shmData{
    char number[4];
    char description[1020];
};

これが私のコードです:

//Structure Pointer - placed on SHM
struct shmstruct *ptr;
char description_to_write[1024] = {0};
struct shmData *data_ptr;
data_ptr = (struct shmData*) description_to_write;

//Shared Memory init
create_shm(&ptr);
printf("Started\n");

//Define Offsets
//init_shm(ptr);

//#########################

//Check if number exist
    if (!(strcmp("NO SUCH CODE\0", get_description(ptr, 6)))) {
        //-> If not, get next offset (nput) where to write new data
//      sem_wait(&ptr->mutex);
//      long offset = ptr->msgoff[ptr->nput];
//      printf("OFFSET: %li\n", offset);
//      if (++(ptr->nput) > NMESG)
//          ptr->nput = 0; /* circular buffer */
//      sem_post(&ptr->mutex);
//      printf("Buffer: %s", argv[2]);

    snprintf(data_ptr->number, 4, "%s", "6");
    snprintf(data_ptr->description, 1020, "%s\n", argv[2]);

    printf("DATA: %s\n", data_ptr->number);
    printf("DATA: %s\n", data_ptr->description);

    printf("description_to_write: %i\n", description_to_write);

    //strcpy(&ptr->msgdata[offset], );
    //sem_post(&ptr->nstored);
    //printf("Wrote...\n\n");
} else {
    //-> Else get offset of this number and put data to it
}

これはどう書けばいいですか?上記のコードでは、単純に説明配列を表示しようとしましたが、数値しか返されませんでした。

次のように共有メモリに書き込む必要があります。

Number(space)(space)(space)Description

共有メモリ ダンプは次のようになります。

00003b0: 3120 2020 496e 7075 7420 4572 726f 720a  1   Input Error.
00003c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00007b0: 3220 2020 4f75 7470 7574 2045 7272 6f72  2   Output Error
00007c0: 0a00 0000 0000 0000 0000 0000 0000 0000  ................
00007d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

デバッガーから:

description_to_write[0] char    54 '6'  
description_to_write[1] char    0 '\000'    
description_to_write[2] char    0 '\000'    
description_to_write[3] char    0 '\000'
description_to_write[4] char    83 'S'  
description_to_write[5] char    111 'o' 
description_to_write[6] char    109 'm' 
description_to_write[7] char    101 'e' 
description_to_write[8] char    84 'T'  
description_to_write[9] char    101 'e' 
description_to_write[10]char    120 'x' 
description_to_write[11]char    116 't' 
description_to_write[12]char    10 '\n' 

醜い解決策:

int i = 0;
        while(i < 4){
            if(data_ptr->number[i] == '\000'){
                data_ptr->number[i] = 32;
            }
            i++;
        }
4

2 に答える 2

4

snprintf に渡される 4 は、書き込む文字の最大数を指定します。書く量ではありません。snprtinf は、書き込んだ文字数を返します。したがって、1文字のみを出力しているため、その後に3つのヌルが残ります。

ただ行う:

snprintf(data->number,4,"%s    ","6");

そうすれば、文字列とそれに続く 4 つのスペースを印刷しようとし、最大 4 文字を印刷します。

于 2013-01-24T05:53:53.860 に答える
1

snprintf()使用して「\ 0」文字をスペースとして書き換える醜いソリューションには、いくつかの欠陥があります。

  • snprintf()に数字を書き込むことはありませんdata_ptr->number[3]。3 文字を超える文字列の場合、ソース文字列の 4 番目の文字をコピーする代わりに、切り捨てて '\0' を書き込みます。

  • 呼び出す前に構造体がゼロ初期化されることが確実でない限り、書き込みが必要なsnprintf()'\0' の後の文字は によって何も設定されません。投稿されたコードでは問題にならないかもしれませんが、構造体がどのように割り当てられて初期化されるかが変更されると、脆弱になります。snprintf()snprintf()data_ptr

フィールドが非常に小さいため、次のように考えることができます。

memset( data_ptr->number, ' ', sizeof(data_ptr->number));
memcpy( data_ptr->number, "6", strlen("6"));

ソース文字列がフィールド サイズよりも長くなる可能性がある場合は、もう少しロジックを追加する必要があるという欠点があります。また、1 つまたは 2 つ以上の場所で行うことであれば、簡単にコピー/貼り付けのバグの原因になる可能性があります。

代わりに使用できる軽くテストされた関数を次に示します (ただし、名前が嫌いであることは認めます)。

size_t str2mem_padded( char* dest, size_t dest_size, char const* src, char fill)
{
    size_t result = 0;

    while (dest_size && *src) {
        *dest++ = *src++;
        ++result;
        --dest_size;
    }
    while (dest_size) {
        *dest++ = fill;
        --dest_size;
    }

    return result; // returns number of chars copied from src so you 
                   //   can determine if there was truncation
}

コードでは、 への呼び出しの代わりに次を使用できますsnprintf(data_ptr->number, 4, "%s", "6")

str2mem_padded( data_ptr->number, sizeof(data_ptr->number), "6", ' ');

うわー、それは私が思っていたよりもはるかに多くの努力でした.

于 2013-01-24T08:04:59.267 に答える