2009-06-08 27 views
7

文字配列で読み込むプログラムがあります。メモリ内の文字列の値が16進数0x01020304と等しくなければなりません。これらはすべて非ASCII文字です。ですから、問題は、非ASCII文字を実行時に文字列リテラル変数に渡すにはどうすればいいですか?C/C++の文字列リテラルに非ASCII文字を挿入する方法

+0

これはCまたはC++の質問ではありません。あなたはあなたの特定の端末でそれを行う方法を見つける必要があります。 0x03は送信するとプロセスが終了することが多いため、特に問題がある可能性があります。 – Don

+0

@ Don:制御端末に渡されるストレート0x03は、データ入力方法(キーボードによる値の入力など)によってはそうでない場合があります。問題は、OPが入力を受け取ることを予期している方法で少し曖昧です。 –

答えて

17

エスケープシーケンスを使用します。文字を正しい順序で入れてください。

"\x01\x02\x03\x04" 

編集:あなたは、単に、既存のchar配列に順序を置くでそれを割り当てる必要がある場合

char s[4]; 

// ... later ... 
s[0] = 0x01; 
s[1] = 0x02; 
s[2] = 0x03; 
s[3] = 0x04; 
(int32_t *)sをキャストして番号を割り当てるしようとしないでください

、char配列正しいアラインメントを持っていません。

+1

私は自分のプログラムに値をコーディングしていても動作しますが、実行時に値を入力できる必要があります。申し訳ありませんが質問が十分ではなかった場合。 –

+1

ベン、それに応じてあなたの質問を更新してください。 – avakar

2

文字列リテラルが必要ですか?

これらはすべて、かなり似ています。

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

あなたは確かに非常に簡単にあなたのニーズに合わせて三番目の形式を使用することができます。

3

おそらくCで最も簡単なのは、16進エスケープ表記"\x01\x02\x03\x04"を使用することです。 (Xがなければ、値は最近ほぼ同じ人気又は理解されていない、8進数である。)

あるいは、

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

が動作するはず(NULL終端の初期化時に含まれることがあることに気づきますこのような)。

+0

私は自分のプログラムに値をコーディングしていればうまくいくが、実行時に値を入力できる必要がある。申し訳ありませんが質問が十分ではなかった場合。 –

+0

あなたの質問は何ですか?プログラムに参加するには? (これはおそらくあなたの環境をより詳しく記述することを意味するでしょう)プログラムで一度それらを移動するにはどうすればいいですか? –

2

メモリ内の文字列の値がすべてASCII以外の文字である16進数の0x01020304になるようにする必要があります。

4つのcontigiousバイトがメモリにレイアウトされている方法を注意してください、あなたのシステムがビッグエンディアンかリトルエンディアンである場合に依存します。 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を読み取ることができます。

1

ソースをUTF8で保存し、すべての文字列をUTF-8として扱います(または何らかの行StringFromUTF()を使用します)。

ユニバーサルコードページ(はい、UTF-8は実際にはコードページではありません)で作業しないたびに、問題を抱えています。

0

あなたはstd::hexを使用して試してみたいことがあります。

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

あなたはその後、例えば、各文字の16進値で入力します。 01 11 7F AA

0

std::wcinおよびstd::wcoutは、コンソールのユニコードサポートに使用できます。しかし、彼らが標準の一部であるかどうかはわかりません。

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); 

君は。マシンのエンディアンが目的の出力エンディアンと一致しない場合は、のみをにする必要があります。

コンパイラまたはCライブラリによって設定された特定の定義を見ることで、エンディアンを見つけることができます。少なくともglibc(Linux)では、endian.hはこのような定義を提供し、byteswap.hはバイトスワッピング機能も提供します。

1

あなたは注射について話しているので、私はあなたに手がかりを与えます(これは、学術目的のためにバッファオーバーフローの脆弱性を悪用するコードインジェクションに役立ちます)...ユニコードを受け入れるように端末を設定する必要があります私のマックでは、デフォルトでそれらを書くことができます)。だから、例えば∫のようなものを書くと、ユニコード文字を入力すると、通常のcharのように1バイトだけメモリに格納されず、2バイト、3バイト、または4バイトになります。配列

char v[4]; 

、あなたが

gets(v); //insecure function to read 

を使用し、メモリ内のVを取る4バイト(10進数)この値で埋められます。この∫ を入力したとします。

-30 
-120 
-85 
0 

これらの単一の位置のいずれかが表示されても、それらのどれもが印刷可能なASCIIではありません。メモリに入ってプログラムをハッキングすることによって同じバッファオーバーフローを利用してスタック内のリターンディレクトリを変更するgets()を可能にする脆弱性。 (コンパイル時にすべてがどのように見えるかを見るために、コードを16進エディタで開きます)!

だから、あなただけの誰もが、メモリがスタックhttp://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/

に割り当てられているかのアイデアを得ることができます。このリンクでファイルに

を印刷することで、あなたが必要なものと一致し、右Unicode文字を見つけなければなりません(@Benにはアカウントがなくても、それを必要とする安全なプログラミングを学んでいる人には)

関連する問題