首页 > 解决方案 > 需要一个像 read() 这样的函数,它将整数数据读入缓冲区并获得与 read() 相同的缓冲区值

问题描述

当我标准输入相同的整数时,如何将整数转换为与使用 read(0,buff,nbytes) 获得的缓冲区相同的值/编码字符?我正在尝试编写类似 read() 的东西,但使用整数数据代替读入缓冲区的文件描述符参数。

like_read(int data,void *buff,size_t nbytes);

它应该与 read() 类似,因为它应该读入缓冲区的值与 read(0,buff,nbytes) 从标准输入到其缓冲区的值相同。例如,当我直接提供整数地址作为缓冲区而不首先使用 read(0,buff,nbytes) 时

int Integer=25
int nbytes=2;
int rlen,wlen,wlen1;
int fd = open("ttyusb.txt", O_RDWR | O_CREAT,0777);
wlen = write(fd, &Integer, nbytes);
wlen1 = write(1, &Integer, nbytes);//for stdout
close(fd);

预期产出

25

实际输出/文件内容是一些编码字符

,它没有给我想要的结果,因为首先使用 read() 从 stdin 将整数读入缓冲区,然后使用 write() 将该缓冲区写入文件,例如:

int Integer;
int nbytes=2;
int rlen,wlen;
int fd = open("ttyusb.txt", O_RDWR | O_CREAT,0777);
rlen = read(0, &Integer, nbytes);
wlen = write(fd, &Integer, nbytes);
wlen1 = write(1, &Integer, nbytes);//for stdout
close(fd);

标准输入

25

预期产出

25

实际输出/文件内容

25

当我在读取(0,缓冲区,nbytes)之后打印缓冲区值时,它会给出一些编码值:

int Integer, nbytes=2;
int fd = open("ttyusb.txt", O_RDWR | O_CREAT,0777);
rlen = read(0, &Integer, nbytes);
wlen = write(fd, &Integer, nbytes);
wlen1 = write(1, &Integer, nbytes);
printf("\nInteger buffer value %d\n",Integer);
close(fd);

标准输入 0 打印“整数缓冲区值 2608”,标准输入 1 打印“整数缓冲区值 2609”,标准输入 2 打印“整数缓冲区值 2610”,.....stdin 9 打印“整数缓冲区值 2617”...

read() 使用什么编码来转换整数值,我如何在没有 read() 的情况下进行转换?

标签: clinuxencodingfile-ioformat

解决方案


我不太确定您要实现什么,但我的解释是您正在尝试将 an 的字节复制int到缓冲区中。可以这样实现:

#include <string.h>

void like_read(int data, void *buff, size_t nbytes)
{
    size_t n;

    /* Limit number of bytes to copy from data variable. */
    n = sizeof(data);
    if (n < nbytes)
        n = nbytes;
    /* Copy bytes from data variable to the buffer. */
    memcpy(buff, &data, n);
    /* If destination buffer is larger than data variable, ... */
    if (n < nbytes) {
        /* ... set the remaining bytes in the destination to all zero. */
        memset((char *)buff + n, 0, nbytes - n);
    }
}

read() 使用什么编码来转换整数值,我如何在没有 read() 的情况下进行转换?

read()至少在 Unix 和 Linux 等 POSIX 类型系统上,只从文件描述符中读取原始数据字节,而不进行任何转换。其他一些操作系统(例如 Microsoft Windows)允许使用特殊标志打开文件,这些标志对原始数据字节进行一些转换,主要用于处理具有不同编码的文本文件。

上面函数中的memcpy()调用将like_read原始数据字节从一个内存位置复制到另一个内存位置,而不进行任何转换。


编辑

我仍然不确定您(OP)正在尝试实现什么,但根据您在下面的评论,也许您正在使用一个函数,该函数将整数值作为十进制 ASCII 字符“打印”到带有换行符的缓冲区,但截断为指定的字节数。这几乎可以做到,snprintf()但该函数总是将终止的空字节写入缓冲区(如果缓冲区大小至少为 1),所以这不是我认为你想要的。因此,snprintf()可用于将整数值打印到足够大小的中间缓冲区,然后memcpy将结果打印到指定缓冲区。这是一个实现:

#include <string.h>
#include <stdio.h>

void like_read(int data, void *buff, size_t nbytes)
{
    char tempbuf[24]; /* ought to be large enough... */
    size_t n;

    /* Print data value to temporary buffer. */
    n = snprintf(tempbuf, sizeof(tempbuf), "%d\n", data);
    /* n is number of bytes that would be printed to tempbuf if room. */
    /* Limit number of bytes to copy to size of temporary buffer. */
    if (n > sizeof(tempbuf))
        n = sizeof(tempbuf);
    /* Limit number of bytes to copy to nbytes. */
    if (n > nbytes)
        n = nbytes;
    /* Copy bytes from tempbuf to the buffer. */
    memcpy(buff, tempbuf, n);
    /* If destination buffer is larger than n, ... */
    if (n < nbytes) {
        /* ... set the remaining bytes in the destination to all zero. */
        memset((char *)buff + n, 0, nbytes - n);
    }
}

推荐阅读