C 扫描来自用户的位输入

C 扫描来自用户的位输入,c,C,我想知道扫描…输入的最佳方式是什么。。假设来自用户的16位。(exp:[0 1 0 0 1 1 0…) 我将使用简短的int 让我们假设每个比特代表一些属性。 我希望用户能够通过两种方式给我输入(一些位的排列): 第一种方式:所有16位都初始化为零,用户将给我他想要打开的位的点: 短整数a=0;(看起来像[000000…0]) 假设用户选择3,5 因此,我知道我可以创建一个初始化为零的掩码,将请求的位置(即1)替换为如下所示: 短整数掩码=0x1; mask如果您不担心内存使用(无论如何,它并不

我想知道扫描…输入的最佳方式是什么。。假设来自用户的16位。(exp:[0 1 0 0 1 1 0…) 我将使用简短的int

让我们假设每个比特代表一些属性。 我希望用户能够通过两种方式给我输入(一些位的排列):

第一种方式:所有16位都初始化为零,用户将给我他想要打开的位的点:

短整数a=0;(看起来像[000000…0])

假设用户选择3,5

因此,我知道我可以创建一个初始化为零的掩码,将请求的位置(即1)替换为如下所示:

短整数掩码=0x1;
mask如果您不担心内存使用(无论如何,它并不多),您可以将输入作为字符串,然后使用
strtol
(来自
stdlib.h
)或类似函数将其转换为整数

我建议
strtol
,因为您可以在这里指定转换的基础


在您的第一种方法中,我看到一个限制,即如果设置位(
1
s)的数量较大,则会给用户带来不便。

由于两个输入的语法不同,因此允许两者都使用

// pseudo code
fgets(buffer,...);
if (IsSyntax1(buffer)) {
  a = ProcesssPerSyntax1(buffer, a);
else if (IsSyntax2(buffer)) {
  a = ProcesssPerSyntax2(buffer, a);
else Error();
示例语法分析器

char *endptr;
// looking for 16-digit binary number
unsigned long tmp = strtoul(buffer, &endptr, 2);
if (endptr == &buffer[16] && *endptr == '\n') {
  a = (short) tmp;
}
else {
  // Search for comma separated 0-15 offsets
  char *p = buffer;
  unsigned mask = 0;
  do {
    unsigned long index = strtoul(p, &endptr, 10);
    if (index >= 16) return fail;
    if ((*endptr != ',') && (*endptr != '\n')) return fail;
    if (endptr == p) return fail;
    mask |= 1U << (unsigned) index; 
    p = endptr + 1;
  } while (*endptr == ',');
  a = mask;
}
char*endptr;
//正在查找16位二进制数
无符号长tmp=strtoul(缓冲区和endptr,2);
如果(endptr==&buffer[16]&&&&endptr=='\n'){
a=(短)tmp;
}
否则{
//搜索逗号分隔的0-15偏移量
char*p=缓冲区;
无符号掩码=0;
做{
无符号长索引=strtoul(p和endptr,10);
如果(索引>=16)返回失败;
如果((*endptr!=',')和(*endptr!='\n'))返回失败;
如果(endptr==p)返回失败;

掩码|=1U我认为第一种方法更好。用户不喜欢处理二进制数据。您的第一种方法是干净和可读的。2ndQ:使用
strtoul
strtoull(input_string,NULL,2);
我会使用16位的十六进制表示。使用short int int a=(short int int)strtol(hexastring,NULL,16)为什么是二进制数据?这是什么类型的应用程序?你不能为这些标志提供一些用户友好的名称吗?你不应该在转换之前检查缓冲区长度吗?@Groo(我假设你指的是
strtol(buffer,&endptr,2)
)事先检查缓冲区长度(而不是检查
endptr
)将只捕获非法输入的子集。然后检查
endptr
的值,可以很好地确定有效的语法。也许我没有注意到您的问题?实际上,我指的是
&buffer[16]
,但这只是地址偏移,不是读取操作。没关系。