如何将 4 个字母的 ascii 字复制到 C 中的缓冲区?
How can I copy 4 letter ascii word to buffer in C?
我正在尝试将单词:0x0FF0 复制到缓冲区,但无法这样做。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <time.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
void print_bits(unsigned int x);
int main(int argc, char *argv[])
{
char buffer[512];
unsigned int init = 0x0FF0;
unsigned int * som = &init;
printf("print bits of som now: \n");
print_bits(init);
printf("\n");
memset(&buffer[0], 0, sizeof(buffer)); // reinitialize the buffer
memcpy(buffer, som, 4); // copy word to the buffer
printf("print bits of buffer[0] now: \n");
print_bits(buffer[0]);
printf("\n");
return 0;
}
void print_bits(unsigned int x)
{
int i;
for (i = 8 * sizeof(x)-17; i >= 0; i--) {
(x & (1 << i)) ? putchar('1') : putchar('0');
}
printf("\n");
}
这是我在控制台中得到的结果:
如果我使用 memcpy,为什么我从位打印中得到不同的值?
不知道它是否与大小端有关,但我在这里丢失了 4 位的 1,所以在这两种方法中它都不应该发生。
当你打电话时
print_bits(buffer[0]);
您只是从缓冲区中取出一个字节,将其转换为 unsigned int
,然后将其传递给函数。 buffer
中的其他字节将被忽略。
您没有将字节“0F F0”写入缓冲区。您正在写入平台内部用于存储数字 0x0FF0 的任何字节。这些没有理由必须相同。
当你在 C 中写 0x0FF0
时,大致意味着 "whatever my implementation uses to encode the number four thousand eighty"。那可能是字节串 0F, F0。但它可能不是。
我的意思是,如果 unsigned int init = 0x0FF0;
和 unsigned int init = 4080;
在某些平台上做同样的事情而在其他平台上做不同的事情,那会有多奇怪?但肯定不是所有平台都使用字节字符串“0F F0”存储数字 4,080。
例如,我可能会将 数字 十存储为“10”或 "ten" 或任何其他方式。仅仅因为您存储了数字 10 就期望 "ten"、“10”或任何其他特定字节序列出现在内存中是不合理的,除非您碰巧特别知道您的平台如何存储数字 10。既然你问了这个问题,你就不知道了。
此外,您只打印 buffer[0]
的值,它是一个字符。所以它不可能包含任何版本的 0x0FF0。
您混淆了类型并依赖于您 architecture/platform 的特定设置;这已经破坏了您现有的代码,并且一旦您使用不同的设置进行编译,它可能会变得更加有害。
你的缓冲区是 char[512]
类型,而你的 init
是 unsigned int 类型。
首先,char
是有符号字符还是无符号字符取决于设置。这实际上是相关的,因为它会影响将 char 值提升为 unsigned int 值的方式。请参阅以下代码,该代码演示了使用显式签名和未签名字符的区别:
signed char c = 0xF0;
unsigned char uc = c;
unsigned int ui_from_c = c;
unsigned int ui_from_uc = uc;
printf("Singned char c:%hhd; Unsigned char uc:%hhu; ui_from_c:%u ui_from_uc:%u\n", c, uc, ui_from_c,ui_from_uc);
// output: Singned char c:-16; Unsigned char uc:240; ui_from_c:4294967280 ui_from_uc:240
其次,int
可能由 4 个或 8 个字节表示(可以容纳 "word"),但 char
通常为 1 个字节,因此不能容纳一个"word" 的 16 位。
第三,体系结构可以是大端或小端,这会影响像 0x0FF0
这样需要 2 个字节的常量实际上位于 4 或 8 字节整数表示中的位置。
所以可以肯定的是 buffer[0]
只选择了你认为它所做的一部分,该部分可能会以错误的方式提升为 unsigned int,甚至可能完全是一部分来自 0x0FF0
-literal.
我建议使用固定宽度的整数值来表示整个单词:
#include <stdio.h>
#include <stdint.h>
void print_bits(uint16_t x);
int main(int argc, char *argv[])
{
uint16_t buffer[512];
uint16_t init = 0x0FF0;
uint16_t * som = &init;
printf("print bits of som now: \n");
print_bits(init);
printf("\n");
memset(buffer, 0, sizeof(buffer)); // reinitialize the buffer
memcpy(buffer, som, sizeof(*som)); // copy word to the buffer
printf("print bits of buffer[0] now: \n");
print_bits(buffer[0]);
printf("\n");
return 0;
}
void print_bits(uint16_t x)
{
int i;
for (i = 8 * sizeof(x); i >= 0; i--) {
(x & (1 << i)) ? putchar('1') : putchar('0');
}
printf("\n");
}
我正在尝试将单词:0x0FF0 复制到缓冲区,但无法这样做。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <time.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
void print_bits(unsigned int x);
int main(int argc, char *argv[])
{
char buffer[512];
unsigned int init = 0x0FF0;
unsigned int * som = &init;
printf("print bits of som now: \n");
print_bits(init);
printf("\n");
memset(&buffer[0], 0, sizeof(buffer)); // reinitialize the buffer
memcpy(buffer, som, 4); // copy word to the buffer
printf("print bits of buffer[0] now: \n");
print_bits(buffer[0]);
printf("\n");
return 0;
}
void print_bits(unsigned int x)
{
int i;
for (i = 8 * sizeof(x)-17; i >= 0; i--) {
(x & (1 << i)) ? putchar('1') : putchar('0');
}
printf("\n");
}
这是我在控制台中得到的结果:
如果我使用 memcpy,为什么我从位打印中得到不同的值?
不知道它是否与大小端有关,但我在这里丢失了 4 位的 1,所以在这两种方法中它都不应该发生。
当你打电话时
print_bits(buffer[0]);
您只是从缓冲区中取出一个字节,将其转换为 unsigned int
,然后将其传递给函数。 buffer
中的其他字节将被忽略。
您没有将字节“0F F0”写入缓冲区。您正在写入平台内部用于存储数字 0x0FF0 的任何字节。这些没有理由必须相同。
当你在 C 中写 0x0FF0
时,大致意味着 "whatever my implementation uses to encode the number four thousand eighty"。那可能是字节串 0F, F0。但它可能不是。
我的意思是,如果 unsigned int init = 0x0FF0;
和 unsigned int init = 4080;
在某些平台上做同样的事情而在其他平台上做不同的事情,那会有多奇怪?但肯定不是所有平台都使用字节字符串“0F F0”存储数字 4,080。
例如,我可能会将 数字 十存储为“10”或 "ten" 或任何其他方式。仅仅因为您存储了数字 10 就期望 "ten"、“10”或任何其他特定字节序列出现在内存中是不合理的,除非您碰巧特别知道您的平台如何存储数字 10。既然你问了这个问题,你就不知道了。
此外,您只打印 buffer[0]
的值,它是一个字符。所以它不可能包含任何版本的 0x0FF0。
您混淆了类型并依赖于您 architecture/platform 的特定设置;这已经破坏了您现有的代码,并且一旦您使用不同的设置进行编译,它可能会变得更加有害。
你的缓冲区是 char[512]
类型,而你的 init
是 unsigned int 类型。
首先,char
是有符号字符还是无符号字符取决于设置。这实际上是相关的,因为它会影响将 char 值提升为 unsigned int 值的方式。请参阅以下代码,该代码演示了使用显式签名和未签名字符的区别:
signed char c = 0xF0;
unsigned char uc = c;
unsigned int ui_from_c = c;
unsigned int ui_from_uc = uc;
printf("Singned char c:%hhd; Unsigned char uc:%hhu; ui_from_c:%u ui_from_uc:%u\n", c, uc, ui_from_c,ui_from_uc);
// output: Singned char c:-16; Unsigned char uc:240; ui_from_c:4294967280 ui_from_uc:240
其次,int
可能由 4 个或 8 个字节表示(可以容纳 "word"),但 char
通常为 1 个字节,因此不能容纳一个"word" 的 16 位。
第三,体系结构可以是大端或小端,这会影响像 0x0FF0
这样需要 2 个字节的常量实际上位于 4 或 8 字节整数表示中的位置。
所以可以肯定的是 buffer[0]
只选择了你认为它所做的一部分,该部分可能会以错误的方式提升为 unsigned int,甚至可能完全是一部分来自 0x0FF0
-literal.
我建议使用固定宽度的整数值来表示整个单词:
#include <stdio.h>
#include <stdint.h>
void print_bits(uint16_t x);
int main(int argc, char *argv[])
{
uint16_t buffer[512];
uint16_t init = 0x0FF0;
uint16_t * som = &init;
printf("print bits of som now: \n");
print_bits(init);
printf("\n");
memset(buffer, 0, sizeof(buffer)); // reinitialize the buffer
memcpy(buffer, som, sizeof(*som)); // copy word to the buffer
printf("print bits of buffer[0] now: \n");
print_bits(buffer[0]);
printf("\n");
return 0;
}
void print_bits(uint16_t x)
{
int i;
for (i = 8 * sizeof(x); i >= 0; i--) {
(x & (1 << i)) ? putchar('1') : putchar('0');
}
printf("\n");
}