简体   繁体   中英

Writing \x00 into a file

I have to send a hex command to a USB device.

The command is:

echo -en "\x1b\x70\x00\x19\xfa" > /dev/usb/lp0

If I write it on the terminal, it works. However, in C++ there is a problem with the hex command. \\x00 is detected as a null-terminated string.

I have tried two methods:

std::string cmd = "echo '\\x1b\\x70\\x00\\x19\\xfa' > /dev/usb/lp0";
std::system(cmd.c_str());

Nothing happens.

And:

std::ofstream device;
device.open("/dev/usb/lp0");
device << "\x1b\x70\x00\x19\xfa";
device.close();

The device doesn't do anything.

How can I get around this problem and use the \\x00 string?

Use the write function to write a fixed length of bytes.

And since you're writing binary data I suggest you open the file in binary mode as well, and write actual integer values instead of a string.


Example code

std::ofstream device ("/dev/usb/lp0",std::ofstream::binary);
std::uint8_t const message[] = { 0x1b, 0x70, 0x00, 0x19, 0xfa };
if (device)
    device.write(reinterpret_cast<char const*>(message), sizeof message);

I recommend using an array of unsigned char , rather than a C-string or std::string, to store the command:

const unsigned char usb_cmd[] = { 0x1b, 0x70, 0x00, 0x19, 0xfa };

This way it is obvious to readers that this is a message in a binary protocol, not text and not a nul-terminated string. Also, declared this way, sizeof(usb_cmd) will be the correct number of bytes to write, not one more, and not sizeof(char*) either. If you need to vary the contents of the command at runtime, use a vector<unsigned char> instead.

I would also do the actual write to the device with operating system primitives:

int fd = open("/dev/usb/lp0", O_RDWR);
if (fd == -1) {
    perror("/dev/usb/lp0");
    return -1;
}
ssize_t nwritten = write(fd, usb_cmd, sizeof usb_cmd);
if ((size_t)nwritten != sizeof usb_cmd) {
    if (nwritten < 0) {
        perror("/dev/usb/lp0: write error");
    } else {
        fprintf(stderr, "/dev/usb/lp0: short write (%zu of %zu bytes)\n",
                (size_t)nwritten, sizeof usb_cmd);
    }
    close(fd);
    return -1;
}
close(fd);
return 0;

This way, you can be sure that exactly the correct number of bytes are written, all at once; there are no encoding or buffering layers to interfere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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