简体   繁体   English

如何在C编程的图片中串联var?

[英]How to concatenate vars in c programmed pic?

I programming a 16f84a pic in hitech C to drive a hd44780 lcd. 我用高科技C编程了一个16f84a图片来驱动hd44780液晶显示器。 So far I've got the lcd initialized and can write individual characters and strings to the lcd. 到目前为止,我已经初始化了LCD,并且可以将单独的字符和字符串写入LCD。 Now I need to do something like this: 现在,我需要执行以下操作:

var = 250; var = 250;
lcd_write_string ("MyVar has value: " + var); lcd_write_string (“ MyVar的值:” + var);
so the lcd should show "MyVar has value: 250" 因此,液晶显示器应显示“ MyVar具有值:250”

First of all how should I concatenate a var and a string? 首先,我应该如何连接一个var和一个字符串? second, the variable var contains an 8 bit binary number (0-255 in decimal). 第二,变量var包含8位二进制数(十进制为0-255)。 If var = 23; 如果var = 23; the 8 bit number has to be split into 2 to represent the 2 and the 3 in ascii to then be shown by the lcd. 必须将8位数字拆分为2以代表ascii中的2和3,然后才能由LCD显示。 how can I do this? 我怎样才能做到这一点? It seems I have to do base 10 conversions or a if tree to split all 2 digit numbers to then be shown in the lcd. 看来我必须进行10进制转换或if树来拆分所有2位数字,然后才能在lcd中显示。 Is there an easier way around this? 有没有更简单的方法可以解决此问题?

thanks! 谢谢!

Why don't you just use printf("%d", var) ? 为什么不只使用printf("%d", var)

var = 250;
char *static_msg = "MyVar has value:";
char msg[sizeof(static_msg) + 4];

sprintf(msg, "%s %d", static_msg, var);
lcd_write_string(msg);

Supposing your toolset does not include the standard C library, or that you want to figure out how to do this yourself, here's the approach I would take: 假设您的工具集不包含标准的C库,或者您想自己弄清楚该如何做,那么我将采用以下方法:

Declare a buffer of as many characters as the LCD can display. 声明一个缓冲区,该缓冲区的大小与LCD可以显示的字符数相同。 Write your fixed string into the beginning of that buffer. 将固定的字符串写入该缓冲区的开头。 Determine how many characters wide your variable will be (there's some math I'm leaving out here, but it's a reasonable exercise I think). 确定您的变量将有多少个字符宽(我在这里省略了一些数学运算,但是我认为这是一个合理的练习)。 Using that length, and the length of the fixed string, figure out where in the buffer your number's digits will go. 使用该长度和固定字符串的长度,找出数字在缓冲区中的位置。 Using the same mathematical constructs as before, write the digits into that space, one by one. 使用与以前相同的数学构造,将数字一位一位地写入该空间。 There's a trick of the C language (required by the standard) that lets you figure out the character value of a decimal digit by the expression '0' + digit . C语言有一个技巧(标准要求),可让您通过表达式'0' + digit十进制数字的字符值。 Hopefully, you see how that works. 希望您能看到它是如何工作的。 Finally, terminate the buffer however your lcd_write_string function expects, and call it on the buffer. 最后,根据您的lcd_write_string函数的期望终止缓冲区,并在缓冲区上调用它。

As indicated by other respondents, this essentially implements a small part of the standard library's printf family of functions. 正如其他受访者所指出的那样,这实际上实现了标准库的printf系列功能的一小部分。 I think it's worthwhile to figure out the implementation, even if you can (and should!) use the library in production code. 我认为,即使您可以(并且应该!)在生产代码中使用该库,也应该弄清楚实现方式。

Since this smells vaguely like homework, I'm not elaborating further just yet. 由于这有点像作业的气味,所以我暂时不做进一步说明。 If you need help on specific points, I'll look for updates to the question. 如果您需要特定点的帮助,我将寻找有关该问题的更新。

If the C compiler comes with the standard C library functions, then sprintf can be used similar to printf , in order to produce a string. 如果C编译器随附了标准C库函数,则可以类似于printf来使用sprintf ,以产生一个字符串。

sprintf can be used to produce a formatted string (as char* ), which could presumably be sent to the lcd_write_string function. sprintf可用于生成格式化的字符串(如char* ),该字符串可以发送给lcd_write_string函数。

The problem with sprintf() is you do not know how many bytes you need to allocate before calling sprintf(). sprintf()的问题是您不知道在调用sprintf()之前需要分配多少字节。 I usually use the following ksprintf() as a replacement. 我通常使用以下ksprintf()作为替代。

typedef struct __kstring_t {
  size_t l, m;
  char *s;
} kstring_t;

int ksprintf(kstring_t *s, const char *fmt, ...)
{
  va_list ap;
  int l;
  va_start(ap, fmt);
  l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); // not working with glibc 2.0
  va_end(ap);
  if (l + 1 > s->m - s->l) {
    s->m = s->l + l + 2;
    kroundup32(s->m);
    s->s = (char*)realloc(s->s, s->m);
    va_start(ap, fmt);
    l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap);
  }
  va_end(ap);
  s->l += l;
  return l;
}

To use that: 要使用它:

kstring_t *str = calloc(1, sizeof(kstring_t));
ksprintf(str, "%s, %d\n", aString, aInteger);
ksprintf(str, "a second line: %s\n", aString2);
free(str->s); free(s);

ksprintf() does not work with glibc 2.0 because vsnprintf does not return the number of bytes in the string. ksprintf()不适用于glibc 2.0,因为vsnprintf不会返回字符串中的字节数。 You need to repeatedly double the memory in allocation. 您需要将分配的内存重复增加一倍。 Linux man page "man snprintf" also gives an example. Linux手册页“ man snprintf”也给出了一个示例。 On your system, you should check the behavior of your vsnprintf(), which is C99, not C90 though. 在您的系统上,应该检查vsnprintf()的行为,它的行为是C99,而不是C90。

Another way to do this would be to use lcd_write_string as a function pointer and do this: 另一种方法是将lcd_write_string用作函数指针并执行以下操作:

printf(lcd_write_string,"MyVar has value: %d",var)

This works correctly on CCS Pic C compiler, if lcd_write_string is declared like 如果lcd_write_string声明为像这样,则可以在CCS Pic C编译器上正常工作

void lcd_write_string (char c);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM