2016-11-22 2 views
1

Ich bin ein Neuling in C und auf Stackoverflow. Ich habe ein Problem beim Hinzufügen von Elementen zu einem Bitset, das die ASCII-Tabelle darstellt. Die übergebenen Zeichen sollten das Bitset setzen, das ihrem Wert in Dezimal entspricht (a = 97).Das Setzen eines einzelnen Bits in einem Bitset bewirkt, dass mehrere Bits gesetzt werden.

Aber sie setzen auch andere Bits, die char +/- 32 * a sind. Ich meine "a" würde 97 setzen, aber auch 225, 193, 161, 129, 97, 65, 33, 1.

Warum macht der Code das? Kann mir jemand in die richtige Richtung zeigen? Hier ist mein Code:

#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' ruft nicht definiertes Verhalten für bestimmten Wert von' item'. Verwenden Sie vorzeichenlose Ganzzahlen und Typen mit fester Breite. Verwenden Sie den Debugger, um das Problem zu finden. Und es gibt keine Garantie, dass ein Byte 8 Bits hat. Benutze keine magischen Zahlen. – Olaf

+3

'* this-> data | = 1 << item;' Wie auf Gottes grüner Erde soll das ein bisschen in ein anderes Wort setzen als das erste? –

Antwort

1

Es gibt einige Probleme in Ihrem Code:

  • Sie nicht ein wenig in einer Reihe von unsigned in einem einzigen Schritt einstellen können, müssen Sie das Element des Arrays bestimmen zu modifizieren und welches Bit dieses Elements.

  • Sie sollten nicht schwer Code 8-Bit-Zeichen verwenden CHAR_BIT von <limits.h>

  • Verwenden calloc() einen Speicherblock auf alle Bits Null initialisiert zuzuteilen, es vereinfacht den Code.

  • Sie definieren eine globale Variable bitset. Diese Variable wird nicht verwendet, vielleicht wollten Sie einen Typ definieren?

ist hier eine korrigierte und vereinfachte Version:

#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; 
}