linux将字符串值写为十六进制到串行

时间:2013-09-06 09:08:46

标签: c++ linux string serial-port hex

这是我的问题 我有一个十六进制值的字符串,如

std::string str ="8C000002008E"  

我希望使用

将其写为十六进制到串行输出
write()

我有一个索尼显示器,我想控制。
传递

unsigned char test[6] = {0x8c, 0x00, 0x00, 0x02, 0x00, 08E};

写入方法有效。 但我不知道如何将字符串转换为这样的char数组,尤其是必须在运行时计算char数组的大小。

感谢您的帮助。

这是我的完整代码

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <fcntl.h>
#include <termios.h>

#include <sstream>

using namespace std;
#define TERM_DEVICE "/dev/ttyUSB0"
#define TERM_SPEED "B9600"


int main() {

std::string teststr = "8C000002008E";

int fd, old_flags;

ssize_t length;

char buffer[16];

struct termios term_attr;

fd_set input_fdset;

if ((fd = open(TERM_DEVICE, O_RDWR)) == -1)
   {
    perror("terminal: Can't open device " TERM_DEVICE);
    return(1);
   }
            /* RS232 konfigurieren */
  if (tcgetattr(fd, &term_attr) != 0)
   {
    perror("terminal: tcgetattr() failed");
    return(1);
   }

  cfsetispeed(&term_attr, B9600);
  cfsetospeed(&term_attr, B9600);

  term_attr.c_cflag &= ~PARENB;

  term_attr.c_cflag &= CS8;
  term_attr.c_cflag &= CSIZE;
  term_attr.c_cflag &= CSTOPB;
  term_attr.c_iflag = 0;
  term_attr.c_oflag = OPOST | ONLCR;
  term_attr.c_lflag = 0;
  if (tcsetattr(fd, TCSAFLUSH, &term_attr) != 0)
    perror("terminal: tcsetattr() failed");

  if (tcgetattr(STDIN_FILENO, &term_attr) != 0)
   {
    perror("terminal: tcgetattr() failed");
    return(1);
   }

  old_flags = term_attr.c_lflag;
  term_attr.c_lflag &= ~(ICANON | ECHO);
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
    perror("terminal: tcsetattr() failed");

  while (1)
   {
    FD_ZERO(&input_fdset);
    FD_SET(STDIN_FILENO, &input_fdset);
    FD_SET(fd, &input_fdset);

    if (select(fd+1, &input_fdset, NULL, NULL, NULL) == -1)
      perror("terminal: select() failed");


    unsigned char test[6] = {0x8c, 0x00, 0x00, 0x02, 0x00, 0x8E};

    if (FD_ISSET(STDIN_FILENO, &input_fdset)){
          if ((length = read(STDIN_FILENO, buffer, 16)) == -1)
            perror("terminal: read() failed");
          else
            if (buffer[0] == '\33')
                break;
        else{
              write(fd, test , sizeof(test));
        }
     }


    if (FD_ISSET(fd, &input_fdset))
     {
      if ((length = read(fd, buffer, 16)) == -1)
        perror("terminal: read() failed");
      else
          cout << std::hex << buffer<< endl;

     }
   }

  term_attr.c_lflag = old_flags;
  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
    perror("terminal: tcsetattr() failed");

  printf("Aborted.\n");
  close(fd);

return 0;

}

2 个答案:

答案 0 :(得分:0)

我无法向您提供快速解决方案,但您可以试试这个:

std::string str ="8C000002008E"  
std::vector<unsigned char> vect;
vect.resize(str.length() / 2);
for (size_t i = 0; i < str.length(); ++i)
{
    vect[i] = str[2*i] - ('0' - 7 * (str[2*i] >= '9'));    //it is possible to optimize this
    vect[i] <<= 4;
    vect[i] = str[2*i+1] - ('0' - 7 * (str[2*i+1] >= '9'));  //it is possible to optimize this
}

没试过,但是应该可以,但是,代码真的没有优化,我已经为自己留下了这部分。

此外,假设初始字符串始终包含偶数个字符。

答案 1 :(得分:0)

如果问题只是将字符串转换为char数组,则可以尝试以下操作:

#include <iostream>
#include <sstream>

int main(int argc, char **argv)
{
  const std::string str ="8C000002008E";

  // count the number of character pairs (i.e. bytes) in the string
  // and dynamically allocate an array of the required size
  const int numBytes = str.size() / 2;
  unsigned char* bytes = new unsigned char[numBytes];

  for (int i = 0; i < numBytes; ++i)
  {
    // grab two characters from the string...
    std::string twoChars = str.substr(2 * i, 2);

    // ...and convert them to an integer using a stringstream
    int byte;
    std::stringstream ss(twoChars);
    ss >> std::hex >> byte;

    // store the result in our char array
    bytes[i] = byte;
  }

  //
  // do something with the byte array here
  //

  // deallocate array before exiting
  delete[] bytes;
}

请注意,这假设初始字符串始终包含偶数个字符。处理奇数大小的输入字符串需要一些额外的代码。