如何用sprintf简化语句?
How to simplify statement with the sprintf?
是否可以使用 sprintf 简化此语句?
unsigned char text[50];
void decode (unsigned char* msg)
{
// ON LED
if (strstr (msg, "DO1=1") == msg)
{
LATGbits.LATG1 =1 ; //led1 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO2=1") == msg)
{
LATGbits.LATG0 = 0 ; //LED 2 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO3=1") == msg)
{
LATGbits.LATG13 = 0 ; //LED 3 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO4=1") == msg)
{
LATGbits.LATG14 = 0 ; //LED 4 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO5=1") == msg)
{
LATGbits.LATG12 = 0 ; //LED 5 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
// OFF LED
else if (strstr (msg, "DO1=0") == msg)
{
LATGbits.LATG1 =0 ; //LED 1 off
}
else if (strstr (msg, "DO2=0") == msg)
{
LATGbits.LATG0 = 1 ; //LED 2 off
}
else if (strstr (msg, "DO3=0") == msg)
{
LATGbits.LATG13 = 1 ; //LED 3 off
}
else if (strstr (msg, "DO4=0") == msg)
{
LATGbits.LATG14 = 1 ; //LED 4 off
}
else if (strstr (msg, "DO5=0") == msg)
{
LATGbits.LATG12 = 1 ; //LED 5 off
}
}
从上面的代码可以看出,例如,当在超级终端中输入"DO1=1"
时,LED1会点亮,"DO1=0"
会熄灭LED。与 DO1 至 DO5 相同。答案取决于 LATGbits
.
类型的定义
你可以改成这样:
unsigned char text[50];
void decode (unsigned char* msg)
{
int on = 0;
// ON LED
if (strstr (msg, "DO1=1") == msg)
{
LATGbits.LATG1 =1 ; //led1 on
on = 1;
}
else if (strstr (msg, "DO2=1") == msg)
{
LATGbits.LATG0 = 0 ; //LED 2 on
on = 1;
}
else if (strstr (msg, "DO3=1") == msg)
{
LATGbits.LATG13 = 0 ; //LED 3 on
on = 1;
}
else if (strstr (msg, "DO4=1") == msg)
{
LATGbits.LATG14 = 0 ; //LED 4 on
on = 1;
}
else if (strstr (msg, "DO5=1") == msg)
{
LATGbits.LATG12 = 0 ; //LED 5 on
on = 1;
}
// OFF LED
else if (strstr (msg, "DO1=0") == msg)
{
LATGbits.LATG1 =0 ; //LED 1 off
}
else if (strstr (msg, "DO2=0") == msg)
{
LATGbits.LATG0 = 1 ; //LED 2 off
}
else if (strstr (msg, "DO3=0") == msg)
{
LATGbits.LATG13 = 1 ; //LED 3 off
}
else if (strstr (msg, "DO4=0") == msg)
{
LATGbits.LATG14 = 1 ; //LED 4 off
}
else if (strstr (msg, "DO5=0") == msg)
{
LATGbits.LATG12 = 1 ; //LED 5 off
}
if (on)
{
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
}
由于它完全由相互排斥的选项组成,您可以通过一些明智的重构来摆脱所有 else if
位。
此外,您比较字符串的方式意味着它们必须位于开头,因此您可以不用 strncmp
。
而且,无需将字符串文字复制到缓冲区然后发送缓冲区,您只需发送字符串文字即可。
进行这些更改会导致代码如下:
#define okayReturn { sendString("OK"); return; }
void decode (unsigned char* msg) {
if (strncmp (msg, "DO1=1", 5) == 0) {
LATGbits.LATG1 = 1;
okayReturn;
}
if (strncmp (msg, "DO2=1", 5) == 0) {
LATGbits.LATG0 = 0;
okayReturn;
}
:
if (strncmp (msg, "DO5=0", 5) == 0) {
LATGbits.LATG12 = 1;
return;
}
}
另一种方法是将字符串分成三个部分(DO
、n
和 =v
,其中 n
是 1..5
和v
是 0
或 1
).
然后您可以使用变量指针组合数据驱动方法,例如:
#include <ctype.h>
void decode (unsigned char* msg) {
// Variables to change for each n in DOn=v
static int *vars[] = { &LATGbits.LATG1, &LATGbits.LATG0,
&LATGbits.LATG13, &LATGbits.LATG14, &LATGbits.LATG12 };
// Check content, allowing for upper/lower case.
msg[0] = toupper (msg[0]);
msg[1] = toupper (msg[1]);
if ((msg[0] != 'D') && (msg[1] != 'O')) return;
if ((msg[2] < '1') || (msg[2] > '5')) return;
if (msg[3] != '=') return;
if ((msg[4] != '0') && (msg[4] != '1')) return;
// Special case for LED 1 vs 2-5.
int on = (msg[2] == '1') ? 1 : 0;
// All content validated, make change, first turning on.
if (msg[4] == '1') {
*(vars[msg[2] - '1']) = on;
sendString("OK");
return;
}
// Or turning off.
*(vars[msg[2] - '1']) = 1 - on;
}
注意使用 toupper()
强制前两个字符为大写。这允许您输入任何一种情况,并且它将被相同对待。如果您需要区分大小写,只需删除这两行即可。
虽然这有点复杂,但要短得多,尤其是 如果您以后决定添加更多 LED。
请记住,只有在 vars
中的变量实际上是可寻址的情况下,这才有效。 不会 如果它们是位字段,但即使那样,您也可以使用上面的一些缩短方法来最小化代码长度,从而使其更易于维护:
#include <ctype.h>
void decode (unsigned char* msg) {
// Check content, allowing for upper/lower case.
msg[0] = toupper (msg[0]);
msg[1] = toupper (msg[1]);
if ((msg[0] != 'D') && (msg[1] != 'O')) return;
if ((msg[2] < '1') || (msg[2] > '5')) return;
if (msg[3] != '=') return;
if ((msg[4] != '0') && (msg[4] != '1')) return;
// All content validated, make change, either turning off.
if (msg[4] == '0') {
switch (msg[2]) {
case '1': LATGbits.LATG1 = 0; break;
case '2': LATGbits.LATG0 = 1; break;
case '3': LATGbits.LATG13 = 1; break;
case '4': LATGbits.LATG14 = 1; break;
case '5': LATGbits.LATG12 = 1; break;
}
return;
}
// Or turning on.
switch (msg[2]) {
case '1': LATGbits.LATG1 = 1; break;
case '2': LATGbits.LATG0 = 0; break;
case '3': LATGbits.LATG13 = 0; break;
case '4': LATGbits.LATG14 = 0; break;
case '5': LATGbits.LATG12 = 0; break;
default: return;
}
sendString("OK");
}
这仍然很短,而且只有 一点 不太容易扩展,如果您想添加 LED。但是,如果您必须更新位字段,它仍然结构良好且易于理解。
是否可以使用 sprintf 简化此语句?
unsigned char text[50];
void decode (unsigned char* msg)
{
// ON LED
if (strstr (msg, "DO1=1") == msg)
{
LATGbits.LATG1 =1 ; //led1 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO2=1") == msg)
{
LATGbits.LATG0 = 0 ; //LED 2 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO3=1") == msg)
{
LATGbits.LATG13 = 0 ; //LED 3 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO4=1") == msg)
{
LATGbits.LATG14 = 0 ; //LED 4 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
else if (strstr (msg, "DO5=1") == msg)
{
LATGbits.LATG12 = 0 ; //LED 5 on
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
// OFF LED
else if (strstr (msg, "DO1=0") == msg)
{
LATGbits.LATG1 =0 ; //LED 1 off
}
else if (strstr (msg, "DO2=0") == msg)
{
LATGbits.LATG0 = 1 ; //LED 2 off
}
else if (strstr (msg, "DO3=0") == msg)
{
LATGbits.LATG13 = 1 ; //LED 3 off
}
else if (strstr (msg, "DO4=0") == msg)
{
LATGbits.LATG14 = 1 ; //LED 4 off
}
else if (strstr (msg, "DO5=0") == msg)
{
LATGbits.LATG12 = 1 ; //LED 5 off
}
}
从上面的代码可以看出,例如,当在超级终端中输入"DO1=1"
时,LED1会点亮,"DO1=0"
会熄灭LED。与 DO1 至 DO5 相同。答案取决于 LATGbits
.
你可以改成这样:
unsigned char text[50];
void decode (unsigned char* msg)
{
int on = 0;
// ON LED
if (strstr (msg, "DO1=1") == msg)
{
LATGbits.LATG1 =1 ; //led1 on
on = 1;
}
else if (strstr (msg, "DO2=1") == msg)
{
LATGbits.LATG0 = 0 ; //LED 2 on
on = 1;
}
else if (strstr (msg, "DO3=1") == msg)
{
LATGbits.LATG13 = 0 ; //LED 3 on
on = 1;
}
else if (strstr (msg, "DO4=1") == msg)
{
LATGbits.LATG14 = 0 ; //LED 4 on
on = 1;
}
else if (strstr (msg, "DO5=1") == msg)
{
LATGbits.LATG12 = 0 ; //LED 5 on
on = 1;
}
// OFF LED
else if (strstr (msg, "DO1=0") == msg)
{
LATGbits.LATG1 =0 ; //LED 1 off
}
else if (strstr (msg, "DO2=0") == msg)
{
LATGbits.LATG0 = 1 ; //LED 2 off
}
else if (strstr (msg, "DO3=0") == msg)
{
LATGbits.LATG13 = 1 ; //LED 3 off
}
else if (strstr (msg, "DO4=0") == msg)
{
LATGbits.LATG14 = 1 ; //LED 4 off
}
else if (strstr (msg, "DO5=0") == msg)
{
LATGbits.LATG12 = 1 ; //LED 5 off
}
if (on)
{
sprintf(text,"OK"); // Send the result in HyperTerminal
sendString(text) ;
}
}
由于它完全由相互排斥的选项组成,您可以通过一些明智的重构来摆脱所有 else if
位。
此外,您比较字符串的方式意味着它们必须位于开头,因此您可以不用 strncmp
。
而且,无需将字符串文字复制到缓冲区然后发送缓冲区,您只需发送字符串文字即可。
进行这些更改会导致代码如下:
#define okayReturn { sendString("OK"); return; }
void decode (unsigned char* msg) {
if (strncmp (msg, "DO1=1", 5) == 0) {
LATGbits.LATG1 = 1;
okayReturn;
}
if (strncmp (msg, "DO2=1", 5) == 0) {
LATGbits.LATG0 = 0;
okayReturn;
}
:
if (strncmp (msg, "DO5=0", 5) == 0) {
LATGbits.LATG12 = 1;
return;
}
}
另一种方法是将字符串分成三个部分(DO
、n
和 =v
,其中 n
是 1..5
和v
是 0
或 1
).
然后您可以使用变量指针组合数据驱动方法,例如:
#include <ctype.h>
void decode (unsigned char* msg) {
// Variables to change for each n in DOn=v
static int *vars[] = { &LATGbits.LATG1, &LATGbits.LATG0,
&LATGbits.LATG13, &LATGbits.LATG14, &LATGbits.LATG12 };
// Check content, allowing for upper/lower case.
msg[0] = toupper (msg[0]);
msg[1] = toupper (msg[1]);
if ((msg[0] != 'D') && (msg[1] != 'O')) return;
if ((msg[2] < '1') || (msg[2] > '5')) return;
if (msg[3] != '=') return;
if ((msg[4] != '0') && (msg[4] != '1')) return;
// Special case for LED 1 vs 2-5.
int on = (msg[2] == '1') ? 1 : 0;
// All content validated, make change, first turning on.
if (msg[4] == '1') {
*(vars[msg[2] - '1']) = on;
sendString("OK");
return;
}
// Or turning off.
*(vars[msg[2] - '1']) = 1 - on;
}
注意使用 toupper()
强制前两个字符为大写。这允许您输入任何一种情况,并且它将被相同对待。如果您需要区分大小写,只需删除这两行即可。
虽然这有点复杂,但要短得多,尤其是 如果您以后决定添加更多 LED。
请记住,只有在 vars
中的变量实际上是可寻址的情况下,这才有效。 不会 如果它们是位字段,但即使那样,您也可以使用上面的一些缩短方法来最小化代码长度,从而使其更易于维护:
#include <ctype.h>
void decode (unsigned char* msg) {
// Check content, allowing for upper/lower case.
msg[0] = toupper (msg[0]);
msg[1] = toupper (msg[1]);
if ((msg[0] != 'D') && (msg[1] != 'O')) return;
if ((msg[2] < '1') || (msg[2] > '5')) return;
if (msg[3] != '=') return;
if ((msg[4] != '0') && (msg[4] != '1')) return;
// All content validated, make change, either turning off.
if (msg[4] == '0') {
switch (msg[2]) {
case '1': LATGbits.LATG1 = 0; break;
case '2': LATGbits.LATG0 = 1; break;
case '3': LATGbits.LATG13 = 1; break;
case '4': LATGbits.LATG14 = 1; break;
case '5': LATGbits.LATG12 = 1; break;
}
return;
}
// Or turning on.
switch (msg[2]) {
case '1': LATGbits.LATG1 = 1; break;
case '2': LATGbits.LATG0 = 0; break;
case '3': LATGbits.LATG13 = 0; break;
case '4': LATGbits.LATG14 = 0; break;
case '5': LATGbits.LATG12 = 0; break;
default: return;
}
sendString("OK");
}
这仍然很短,而且只有 一点 不太容易扩展,如果您想添加 LED。但是,如果您必须更新位字段,它仍然结构良好且易于理解。