此代码有效,但我想知道是否有更好的方法。基本上我需要测试位,并根据位的状态将适当的字符或字符写入字符串。存在空格是因为字符将以固定宽度字体显示,并且我希望它们不会移动。 C或C ++很好。
const char* Letters[10] = {"A", "B", "Sl", "St", "R", "L", "U", "D", "RS", "LS"};
const char* Ext[2] = {"X", "Y"};
const char* Spaces[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
char str[60];
char FinalString[60];
void MakeBitString(u16 data, u16 dataExt) {
int x;
strcpy(str, "");
for (x = 0; x < 2; x++) {
//X and Y
if(dataExt & (1 << x)) {
strcat(str, Spaces[x]);
}
else
strcat(str, Ext[x]);
}
for (x = 0; x < 10; x++) {
//the rest
if(data & (1 << x)) {
strcat(str, Spaces[x]);
}
else
strcat(str, Letters[x]);
}
strcpy(FinalString, str);
}
答案 0 :(得分:4)
答案 1 :(得分:3)
我推荐一些更明确的东西,它不使用循环,因为你似乎只有少量的位要检查。如果需要扩展到数万位,那么一定要使用循环。
我还假设您有充分的理由使用全局变量和固定长度的字符数组。
以下是我要做的事情:
char FinalString[60];
void ConcatBitLabel(char ** str, u16 data, u16 bitMask, const char * label)
{
if (data & bitMask)
{
// append spaces for strlen(label)
while (*label) { *((*str)++) = ' '; label++; }
}
else
{
// append the label
while (*label) { *((*str)++) = *label; label++; }
}
}
void MakeBitString(u16 data, u16 dataExt)
{
char * strPtr = FinalString;
ConcatBitLabel(&strPtr, dataExt, 0x0001, "X");
ConcatBitLabel(&strPtr, dataExt, 0x0002, "Y");
ConcatBitLabel(&strPtr, data, 0x0001, "A");
ConcatBitLabel(&strPtr, data, 0x0002, "B");
ConcatBitLabel(&strPtr, data, 0x0004, "Sl");
ConcatBitLabel(&strPtr, data, 0x0008, "St");
ConcatBitLabel(&strPtr, data, 0x0010, "R");
ConcatBitLabel(&strPtr, data, 0x0020, "L");
ConcatBitLabel(&strPtr, data, 0x0040, "U");
ConcatBitLabel(&strPtr, data, 0x0080, "D");
ConcatBitLabel(&strPtr, data, 0x0100, "RS");
ConcatBitLabel(&strPtr, data, 0x0200, "LS");
*strPtr = 0; // terminate the string
}
答案 2 :(得分:3)
基本上C ++解决方案看起来像
Codes convert( std::size_t data,
const Codes& ext,
const Codes& letters )
{
Codes result;
std::transform( ext.begin(),
ext.end(),
std::back_inserter( result ),
Converter( data ) );
std::transform( letters.begin(),
letters.end(),
std::back_inserter( result ),
Converter( data ) );
return result;
}
Converter
的实施方式,如
struct Converter
{
Converter( std::size_t value ):
value_( value ), x_( 0 )
{}
std::string operator() ( const std::string& bitPresentation )
{
return ( value_ & ( 1 << x_++ ) ) ?
std::string( bitPresentation.size(), ' ' ):
bitPresentation;
}
std::size_t value_;
std::size_t x_;
};
这是从代码转换为字符串函数
std::string codesToString( const Codes& codes )
{
std::ostringstream stringStream;
std::copy( codes.begin(), codes.end(),
std::ostream_iterator<std::string>( stringStream ) );
return stringStream.str();
}
答案 3 :(得分:1)
以一些动态分配为代价(在std :: string内),您可以通过不使用任何硬编码来更容易地修改此代码:
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
std::string MakeBitString(u16 data, const std::string* letters, int count) {
std::string s;
for (int x = 0; x < count; x++) {
if (data & (1 << x))
s.append(letters[x].size(), ' ');
else
s += letters[x];
}
return s;
}
std::string MakeBitString(u16 data, u16 dataExt) {
const std::string Letters[] = {"A", "B", "Sl", "St", "R", "L", "U", "D", "RS", "LS"};
const std::string Ext[] = {"X", "Y"};
std::string s = MakeBitString(dataExt, Ext, ARRAYSIZE(Ext));
s += MakeBitString(dataExt, Letters, ARRAYSIZE(Letters));
return s;
}
答案 4 :(得分:0)
那应该没事;但是,如果你想添加按钮或轴,你可能想稍微概括一下。
答案 5 :(得分:0)
这是一次通过的一点点方式。它甚至可以扩展到最多16位,只要你确保wide
掩码在任何你有2个字符的能指位置都设置了位。
#define EXT_STR "XY"
#define DATA_STR "ABSlStRLUDRSLS"
const char FullStr[] = EXT_STR DATA_STR;
#define EXT_SZ 2 //strlen(EXT_STR);
void MakeBitStr(u16 data, u16 dataExt) {
char* dest = FinalString;
const char* src= FullStr;
u16 input = (data<<EXT_SZ)|dataExt;
u16 wide = (0x30C<<EXT_SZ)|0; //set bit for every 2char tag;
while ((src-FullStr)<sizeof(FullStr))
{ *dest++ = (input&1)?' ':*src;
if (wide&1)
{ wide&=~1;
}
else
{ input>>=1;wide>>=1;
}
src++;
}
*dest='\0';
}
答案 6 :(得分:0)
非hacky,干净的解决方案:
std::string MakeBitString(u16 data, u16 dataExt) {
std::string ret;
static const char *letters = "A B SlStR L U D RSLS";
static const char *ext = "XY";
static const char *spaces = " ";
for(int bit = 0; bit < 2; ++bit) {
const char *which = (dataExt & 1) ? &ext[bit] : spaces;
ret += std::string(which, 0, 1);
dataExt >>= 1;
}
for(int bit = 0; bit < 10; ++bit) {
const int length = letters[bit * 2 + 1] == ' ' ? 1 : 2;
const char *which = (dataExt & 1) ? &letters[bit * 2] : spaces;
ret += std::string(which, 0, length);
dataExt >>= 1;
}
return ret;
}