c - 在 Bitset 中设置单个位会导致设置多个位

标签 c bitset

我是 C 语言和 Stackoverflow 的新手。我在向表示 ASCII 表的位集添加元素时遇到问题。我传递的字符应将位集的位设置为其十进制值 (a=97)。

但他们还设置了其他位,即 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;
}

最佳答案

您的代码中存在一些问题:

  • 您不能在 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;
}

关于c - 在 Bitset 中设置单个位会导致设置多个位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40753740/

相关文章:

c++ - std::bitset 上的位扫描(bsf)?或类似

c++ - long int 的位表示未正确打印

java - Java Map中使用BitSet作为key时如何解决ClassCastException

c - 基本C指针问题

在 C 中我能找到变量属于什么类型吗?

c++ - sscanf 麻烦吗?

java - 将 java BitSet 保存到数据库

c++ - 实现对所有位的加法和访问的位集

c - 单元测试覆盖问题

python - 将图像数组从 Python 传递到 C 会带来损坏的数据