我试图将uint64_t
位域全部设置为0.然后,当我在给定字符串中调用该函数,并且它与我设置的静态全局数组匹配时,它会将该位翻转为1.目前我有以下代码但由于某种原因,当给它不同的字符串时,它遵循相同的行为。例如,当我输入以下字符串" ABC"它应该打印出111000
。我如何得到以下行为。
const size_t SETSIZE = sizeof(uint64_t) << 3;
char key[5] = { 'A', 'B', 'C', 'D', 'E', 'F' }
uint64_t set_encode(char *st) {
int i, j;
uint64_t set = 0;
int length = strlen(st);
for (i = 0; i < length; i++) {
for (j = 0; j < 5; j++) {
if (st[i] == key[j]) {
printf("%c", st[0]);
set = set | 1 << (SETSIZE - 1 - i);
}
}
}
printf("%lu\n", set);
return set;
}
答案 0 :(得分:1)
Or-ing使用int
编码,而非uint64_t
1 <<(SETSIZE-1-i)
会生成int
类型。此外,可能UB作为一些移位计数肯定比int
更宽。
// set = set| 1 <<(SETSIZE-1-i);
set |= ((uint64_t) 1) <<(SETSIZE-1-i);
可疑的打印说明符。 "%lu"
可能无法锁定uint64_t
。
#include <inttypes.h>
// printf("%lu\n",set);
printf("%" PRIu64 "\n", set);
// Perhaps print as hexadecimal makes more sense
printf("%" PRIX64 "\n", set);
请注意,key[]
太小了。
// char key[5] = {'A','B','C','D','E','F'}
char key[5+1] = {'A','B','C','D','E','F'}
// or
char key[] = {'A','B','C','D','E','F'}
为什么要打印st[0]
// printf("%c",st[0]);
printf("%c",st[i]);
即使进行了修理,OP的最终目标也不明确也无法获得。
答案 1 :(得分:0)
代码中存在多个问题:
const size_t SETSIZE = sizeof(uint64_t) << 3;
字节可能不是8位,您应该使用const size_t SETSIZE = 64;
,因为uint64_t
类型(如果存在)被定义为具有2的补码表示的64位宽。
char key[5] = { 'A', 'B', 'C', 'D', 'E', 'F' }
初始值设定项有6个字符,但显式大小设置为5
。使用char key[] = { 'A', 'B', 'C', 'D', 'E', 'F' };
。请注意,key
不是C字符串,因为初始值设定项中不存在'\0'
。另请注意,初始化程序末尾缺少;
。
uint64_t set_encode(char *st) {
您不会修改st
指向的字符串,请使用const char *st
int i, j;
i
和j
应定义为size_t
,以便与length
保持一致。
uint64_t set = 0;
int length = strlen(st);
返回类型为size_t
,因为字符串的长度可能大于int
的范围。在您的特定情况下,它不是基本的,因为该函数仅对最多64个字符的字符串有用,您还应该测试它。
for (i = 0; i < length; i++) {
for (j = 0; j < 5; j++) {
j
应与sizeof(key)
进行比较。
if (st[i] == key[j]) {
printf("%c", st[0]);
您可能希望打印st[i]
而不是st[0]
。
set = set | 1 << (SETSIZE - 1 - i);
使用从最低值到最高值的位可能更加一致,并且必须将1
强制转换为(uint64_t)
以避免int
上的字符串更长的算术溢出超过31个字符(如果int
为32位宽):set = set | (uint64_t)1 << i;
。但请注意,即使使用演员表,对于大于63或负值的移位量,移位操作仍未定义。
}
}
}
printf("%lu\n", set);
set
不一定是long
。您可以将其打印为至少64位宽的unsigned long long
:printf("%llu\n", (unsigned long long)set);
或者您可以使用<inttypes.h>
中的格式说明符:printf("%"PRIu64"\n", set);
return set;
}
以下是更正版本:
const size_t SETSIZE = 64;
char key[] = { 'A', 'B', 'C', 'D', 'E', 'F' };
uint64_t set_encode(const char *st) {
uint64_t set = 0;
size_t length = strlen(st);
if (length > SETSIZE) {
printf("string too long: %zd bytes\n", length);
length = SETSIZE;
}
for (size_t i = 0; i < length; i++) {
for (size_t j = 0; j < sizeof(key); j++) {
if (st[i] == key[j]) {
printf("%c", st[i]);
set |= (uint64_t)1 << i;
}
}
}
printf("%llu\n", (unsigned long long)set);
return set;
}