ビット演算子を使って顔文字を以下のように出力させたいのですか、このコードで出力させると何も出ず、エラーが出ていまい終わるだけです。
どうすれば一文字ずつ消えるように出力させるでしょうか?
<結果>
Σ(・ω・ノ)ノ!
(・ω・ノ)ノ!
・ω・ノ)ノ!
ω・ノ)ノ!
・ノ)ノ!
ノ)ノ!
)ノ!
ノ!
!
文字列とビット演算子について教えてください。
Re: 文字列とビット演算子について教えてください。
一文字ずつ消すように出力の開始位置をずらしていくといいでしょう。
…あっ、これだとビット演算子を使っていませんね。どこか適当にねじ込んでください。
#include<stdio.h>
int main(void){
int i, j;
char kaomozi[] = "Σ(・ω・ノ)ノ!";
for (i = 0; kaomozi[i]; i++){
printf("%s", kaomozi + i);
printf("\n");
#if 1
/* Shift-JISの場合 */
j = (unsigned char)kaomozi[i];
if (((0x81 <= j && j <= 0x9f) || (0xe0 <= j && j <= 0xef))){
j = (unsigned char)kaomozi[i + 1];
if (0x40 <= j && j != 0x7f && j <= 0xfc) i++;
}
#else
/* UTF-8の場合 (不正チェックは省略) */
j = (unsigned char)kaomozi[i];
if (0xfe <= j) ; /* 不正なので進めない */
else if (0xfc <= j) i += 5;
else if (0xf8 <= j) i += 4;
else if (0xf0 <= j) i += 3;
else if (0xe0 <= j) i += 2;
else if (0xc0 <= j) i++;
#endif
}
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 文字列とビット演算子について教えてください。
そもそも、今回の問題をビット演算子で解決しようとするもくろみそのものが適切ではないのではないか、という気がします。
そんなことはないかな?
そんなことはないかな?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: 文字列とビット演算子について教えてください。
文字列はマルチバイトです。バイト列です。ビット演算子は不要です。かごめ さんが書きました:そういう課題なんで必要です。
課題を一字一句変えずに書いてください。
とりあえず、プログラムを作ってみました。
VC++ では、このままいけると思います。
cygwin だと、set LANG=ja_JP.cp932 を実行した後だと大丈夫だと思います。
Linux では、環境変数 LANG=ja_JP.UTF-8 だと思うので、OK でしょう。
コンパイル時の警告は無視してください。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main(void)
{
int i, n;
wchar_t k[16];
char *p = (char *)k;
char kaomozi[] = "Σ(・ω・ノ)ノ!";
setlocale(LC_ALL, "");
n = mbstowcs(k, kaomozi, 16);
for (i = 0; i < n; i++)
printf("%ls\n", p + (i << (sizeof(wchar_t)>>1)));
return 0;
}
それと、あなたの環境(OS やコンパイラ)が何かを書いてください。
Re: 文字列とビット演算子について教えてください。
例えば、整数の足し算をビット演算子を用いて行うことができます。かごめ さんが書きました:どこに入れればいいのかわからいないので質問しているのですが・・・
#include<stdio.h>
/* 全加算器をシミュレートする */
unsigned int add(unsigned int a, unsigned int b) {
unsigned int pos = 1;
unsigned int carry = 0;
unsigned int answer = 0;
while (pos) {
unsigned int abit = a & pos;
unsigned int bbit = b & pos;
unsigned int digit = abit ^ bbit ^ carry;
unsigned int next_carry = (abit & bbit) | (bbit & carry) | (carry & abit);
answer |= digit;
carry = next_carry << 1;
pos <<= 1;
}
return answer;
}
int main(void){
unsigned int i, j;
char kaomozi[] = "Σ(・ω・ノ)ノ!";
for (i = 0; kaomozi[i]; i = add(i, 1)){
printf("%s", kaomozi + i); /* ここの加算はポインタ演算なので置き換えられない */
printf("\n");
#if 1
/* Shift-JISの場合 */
j = (unsigned char)kaomozi[i];
if (((0x81 <= j && j <= 0x9f) || (0xe0 <= j && j <= 0xef))){
j = (unsigned char)kaomozi[add(i, 1)];
if (0x40 <= j && j != 0x7f && j <= 0xfc) i = add(i, 1);
}
#else
/* UTF-8の場合 (不正チェックは省略) */
j = (unsigned char)kaomozi[i];
if (0xfe <= j) ; /* 不正なので進めない */
else if (0xfc <= j) i = add(i, 5);
else if (0xf8 <= j) i = add(i, 4);
else if (0xf0 <= j) i = add(i, 3);
else if (0xe0 <= j) i = add(i, 2);
else if (0xc0 <= j) i = add(i, 1);
#endif
}
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 文字列とビット演算子について教えてください。
C++を使ってよければ、演算子をオーバーロードすればいいでしょう。
もしくは、<<1を使うなら
#include <stdio.h>
#include <string.h>
class moziretu {
char* data;
public:
moziretu(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
~moziretu() {
delete[] data;
}
// コピーコンストラクタ (The Rule of Three)
moziretu(const moziretu& m) {
data = new char[strlen(m.data) + 1];
strcpy(data, m.data);
}
// 代入演算子 (The Rule of Three)
moziretu& operator=(const moziretu& m) {
delete[] data;
data = new char[strlen(m.data) + 1];
strcpy(data, m.data);
return *this;
}
const char* operator<<(int index) const {
char* pos = data;
int c;
for (; index-- && *pos; pos++) {
#if 1
// Shift-JISの場合
c = (unsigned char)*pos;
if (((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))){
c = (unsigned char)pos[1];
if (0x40 <= c && c != 0x7f && c <= 0xfc) pos++;
}
#else
// UTF-8の場合 (不正チェックは省略)
c = (unsigned char)*pos;
if (0xfe <= c) ; // 不正なので進めない
else if (0xfc <= c) pos += 5;
else if (0xf8 <= c) pos += 4;
else if (0xf0 <= c) pos += 3;
else if (0xe0 <= c) pos += 2;
else if (0xc0 <= c) pos++;
#endif
}
return pos;
}
};
int main(void){
int i;
moziretu kaomozi = "Σ(・ω・ノ)ノ!";
for (i = 0; i < 9; i++){
printf("%s", kaomozi<<i);
printf("\n");
}
return 0;
}
#include <stdio.h>
#include <string.h>
class moziretu {
char* data;
char* pos;
public:
moziretu(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
pos = data;
}
~moziretu() {
delete[] data;
}
// コピーコンストラクタ (The Rule of Three)
moziretu(const moziretu& m) {
data = new char[strlen(m.data) + 1];
strcpy(data, m.data);
pos = data;
}
// 代入演算子 (The Rule of Three)
moziretu& operator=(const moziretu& m) {
delete[] data;
data = new char[strlen(m.data) + 1];
strcpy(data, m.data);
pos = data;
return *this;
}
const char* operator<<(int index) {
int c;
char* ret = pos; // 演算前の値を返すようにする
for (; index-- && *pos; pos++) {
#if 1
// Shift-JISの場合
c = (unsigned char)*pos;
if (((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))){
c = (unsigned char)pos[1];
if (0x40 <= c && c != 0x7f && c <= 0xfc) pos++;
}
#else
// UTF-8の場合 (不正チェックは省略)
c = (unsigned char)*pos;
if (0xfe <= c) ; // 不正なので進めない
else if (0xfc <= c) pos += 5;
else if (0xf8 <= c) pos += 4;
else if (0xf0 <= c) pos += 3;
else if (0xe0 <= c) pos += 2;
else if (0xc0 <= c) pos++;
#endif
}
return ret;
}
};
int main(void){
int i;
moziretu kaomozi = "Σ(・ω・ノ)ノ!";
for (i = 0; i < 9; i++){
printf("%s", kaomozi<<1);
printf("\n");
}
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 文字列とビット演算子について教えてください。
j = (unsigned char)kaomoz; を j = kaomozi & 0xff; とすれば、かごめ さんが書きました:どこに入れればいいのかわからいないので質問しているのですが・・・
ビット演算子 & を使ったことになります。
int le(int a, int b) { return ~(b-a >> 8); }
という関数を用意して
if ((le(081, j) & le(j, 0x9f)) | (le(0xe0, j) & le(j, 0xef))) {
と書けば、& | ~ >> の 4種類のビット演算子を使ったことになります。