如何在C / C ++中将非ASCII字符注入字符串文字

时间:2009-06-08 18:00:45

标签: c++ c

我有一个读入字符数组的程序。我需要内存中字符串的值等于十六进制0x01020304,它们都是非ASCII字符。所以问题是,如何在运行时将非ASCII字符传递给字符串文字变量?

9 个答案:

答案 0 :(得分:17)

使用转义序列。确保按正确顺序放置字符。

"\x01\x02\x03\x04"

编辑:如果您需要将序列放入现有的char数组中,只需将其分配。

char s[4];

// ... later ...
s[0] = 0x01;
s[1] = 0x02;
s[2] = 0x03;
s[3] = 0x04;

不要尝试通过将s强制转换为(int32_t *)来分配号码,但char数组没有正确的对齐方式。

答案 1 :(得分:4)

在C中,最简单的可能是使用十六进制转义表示法:"\x01\x02\x03\x04"。 (没有x,值是八进制的,现在几乎不受欢迎或理解。)

可替换地,

char x[] = {1, 2, 3, 4, 0};

应该有效(请注意,在初始化时必须包含null终止)。

答案 2 :(得分:3)

  

我需要内存中字符串的值等于十六进制0x01020304,它们都是非ASCII字符。

要注意如果您的系统是big-endian或little-endian,内存中如何布置4个可靠的字节将取决于。如果您关心32位字段的工作原理,只需将字符串文字放入字符串文字即可。

例如:

你可以尝试,正如avakar建议的那样:

char cString[5] = "\x01\x02\x03\x04";

甚至只是做

cString[0] = 0x01;
cString[1] = 0x02;
...

但如果您希望内存中的实际物理布局有意义:

// assuming unsigned int is 32 bits
unsigned int* cStringAlias = rentirpret_cast<int*>(&cString[0]);
std::cout << (*cStringAlias)

注意,输出会有所不同,具体取决于最重要的字节是放在第0个位置还是第3个位置。

输出可能是

0x01020304

0x04030201

有关详情,请参阅endianess

答案 3 :(得分:2)

嗯,你确定你需要一个字符串文字吗?

这些都非常相似:

const char* blah = "test";
char blah[] = "test";
char blah[] = { 't','e','s','t',0 };

你当然可以很容易地使用第三种形式来满足你的需求。

答案 4 :(得分:1)

将源保存为UTF8并将所有字符串视为UTF-8(或使用某些行StringFromUTF())。

每次你不在通用代码页中工作(是的,UTF-8实际上不是代码页......)你就是在寻找麻烦。

答案 5 :(得分:1)

编写C代码时,可以使用 memcpy()复制二进制数据:

memcpy(dest + offset, src, 4);

如果 src 是一个字符串,你可能会以正确的顺序得到它。如果它是一个整数(比如uint32_t)并且你需要一个特定的字节序,你可能需要在执行 memcpy()之前颠倒字节的顺序:

uint32_t src;

...

swap((unsigned char *) &src, 0, 3);
swap((unsigned char *) &src, 1, 2);

其中 swap()由您定义。如果机器字节顺序与所需的输出字节顺序不匹配,则必须执行

您可以通过查看编译器或C库设置的某些定义来发现字节序。至少在glibc(Linux)上, endian.h 提供了这样的定义, byteswap.h 也提供了字节交换功能。

答案 6 :(得分:1)

由于您正在谈论注入,我将为您提供线索(这对于利用缓冲区溢出漏洞的代码注入非常有用,出于学术目的)...您必须将终端配置为接受unicode(在我的mac中你可以默认编写它们)。所以你写的例如∫这样的东西,当你输入unicode字符时,它不会像常规字符一样只占用内存中的一个字节,它将需要更多的字节(可以是两个,三个或四个字节),所以如果你有一个字节阵列

char v[4];

如果您使用

gets(v); //insecure function to read

并输入此∫ 在内存中占用v的4个字节将填充此值(十进制):

-30
-120
-85
0

如果你看到这些单个位置中的任何一个,它们都不是可打印的ASCII,那可能是你可以进入内存的某些代码并使程序通过黑客攻击来改变堆栈中的返回目录也可以通过利用它来执行它允许gets()的缓冲区溢出漏洞。 (让代码在HEX编辑器中打开您的程序,以查看编译时的所有内容)!

所以你必须找到与你在文件中打印所需内容相匹配的正确unicode字符

在这个链接中,任何人都可以了解如何在堆栈http://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/

中分配内存

(似乎@Ben甚至没有帐户,但对于正在学习需要它的安全编程的人来说)

答案 7 :(得分:0)

您可能想尝试使用std::hex

int temp;
char sentMessage[10];
        for(int i = 0; i < 10; ++i)
        {
            std::cin >> std::hex >> temp;
            sentMessage[i] = temp;   
        } 

然后输入每个字符的十六进制值,例如。 01 11 7F AA

答案 8 :(得分:0)

您可以使用std::wcinstd::wcout来获得对控制台的unicode支持。但是,我不确定它们是否属于标准。