2016-11-22 10 views
1

私はCとStackoverflowの初心者です。 ASCIIテーブルを表すビットセットに要素を追加する際に問題があります。私が渡す文字は、ビットセットのビットを小数点の値(a = 97)に設定する必要があります。ビットセット内の単一ビットを設定すると、いくつかのビットが設定されます。

しかし、他のビットもchar +/- 32 * aに設定されています。私は97を設定するだけでなく、225,193,161,129,97,65,33,1を意味します。

なぜこのコードが実行されますか?誰かが私を正しい方向に向けることができますか?あなたのコード内のいくつかの問題があります

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

struct bitset { 
    unsigned *data; 
    int size_in_bits; 
    int size_in_words; 
} bitset; 

// create a new, empty bit vector set of 'size' items 
struct bitset *new_bitset(int size) { 
    int word_bits = sizeof(unsigned) * 8; 

    struct bitset *result; 
    result = malloc(sizeof(struct bitset)); 
    result->size_in_bits = size; 

    result->size_in_words = size/word_bits; 
    if (size % word_bits != 0) { 
     result->size_in_words++; 
    } 

    result->data = malloc(sizeof(unsigned) * result->size_in_words); 
    for (int i = 0; i < result->size_in_words; i++) { 
     result->data[i] = 0; 
    } 
    return result; 
} 

// check to see if an item is in the set 
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds 
int bitset_lookup(struct bitset *this, int item) { 
    if (item < 0 || item > this->size_in_bits) { 
     return -1; 
    } 
    if (*this->data & (1 << item)) { 
     return 1; 
    } 
    return 0; 
} 

// add an item, with number 'item' to the set 
// (returns 0 if item is out of bounds, 1 otherwise) 
// has no effect if the item is already in the set 
int bitset_add(struct bitset *this, int item) { 
    if (item < this->size_in_bits) { 
     *this->data |= 1 << item; 
     return 1; 
    } 
    return 0; 
} 

int main() { 
    char str1 = "a"; 
    struct bitset *src1; 

    src1 = new_bitset(256); 

    bitset_add(src1, str1); 

    for (int j = 0; j < src1->size_in_bits; j++) { 
     if (bitset_lookup(src1, j) == 1) { 
      int myChar = j; 
      printf("%d ", myChar); 
     } else 
      printf("0 "); 
    } 
    return 0; 
} 
+2

'1 << item'はitem''の特定の値のための未定義の動作を呼び出します。符号なし整数と固定幅型を使用します。デバッガを使用して問題を見つけます。そして、バイトが8ビットを持つという保証はありません。マジックナンバーは使用しないでください。 – Olaf

+3

'* this-> data | = 1 << item;'神の緑の土はどのように最初の単語以外の単語にもビットを設定するはずですか? –

答えて

1

: はここに私のコードですあなたは、単一のステップでunsignedの配列にビットを設定することはできません

  • が、あなたは、配列のどの要素を決定する必要があります変更する要素とその要素のどのビット。

  • あなたはないハードコードの8ビット文字は、すべてのビットがゼロに初期化されたメモリのブロックを割り当てる<limits.h>

  • 使用calloc()からCHAR_BITを使用する必要があり、それはコードを簡単にします。

  • グローバル変数bitsetを定義します。この変数は使用されていません。おそらくタイプを定義することを意図していますか?ここ

を補正し、簡略化したバージョンである:

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

struct bitset { 
    unsigned *data; 
    int size_in_bits; 
    int size_in_words; 
}; 

// create a new, empty bit vector set of 'size' items 
struct bitset *new_bitset(int size) { 
    int word_bits = sizeof(unsigned) * CHAR_BIT; 
    struct bitset *result = malloc(sizeof(struct bitset)); 

    result->size_in_bits = size; 
    result->size_in_words = (size + word_bits - 1)/word_bits; 
    result->data = calloc(result->size_in_words, sizeof(unsigned)); 
    return result; 
} 

// check to see if an item is in the set 
// returns 1 if in the set, 0 if not, and -1 if 'item' is out of bounds 
int bitset_lookup(struct bitset *this, int item) { 
    int word_bits = sizeof(unsigned) * CHAR_BIT; 

    if (item < 0 || item >= this->size_in_bits) { 
     return -1; 
    } 
    return (this->data[item/word_bits] >> (item % word_bits)) & 1; 
} 

// add an item, with number 'item' to the set 
// (returns 0 if item is out of bounds, 1 otherwise) 
// has no effect if the item is already in the set 
int bitset_add(struct bitset *this, int item) { 
    int word_bits = sizeof(unsigned) * CHAR_BIT; 

    if (item >= 0 && item < this->size_in_bits) { 
     this->data[item/word_bits] |= 1U << (item % word_bits); 
     return 1; 
    } 
    return 0; 
} 

int main(void) { 
    char str[] = "Hello world"; 
    struct bitset *set = new_bitset(256); 

    for (int i = 0; str[i] != '\0'; i++) { 
     bitset_add(set, (unsigned char)str[i]); 
    } 

    for (int j = 0; j < set->size_in_bits; j++) { 
     if (bitset_lookup(set, j) == 1) { 
      printf("%c ", j); 
     } 
    } 
    printf("\n"); 
    return 0; 
} 
関連する問題