2016-11-22 38 views
1

我是C和Stackoverflow的新手。在向代表ASCII表的位集中添加元素時遇到問題。我通過的字符應該設置位對應它們的十進制值(a = 97)的位。在Bitset中設置一位會導致設置幾個位

但他們也設置其他位是char +/- 32 * a。我的意思是「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位字符,使用CHAR_BIT<limits.h>

  • 使用calloc()分配的內存初始化爲所有位零塊,它簡化了代碼。

  • 您可以定義一個全局變量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; 
}