コンパイルエラー!入力文字列をBASE64デコードする関数の作成でエラーが発生しています

このQ&Aのポイント
  • 質問者は入力文字列をBASE64デコードする関数を作成しようとしていますが、L20〜L23の行でコンパイルエラーが発生しています。
  • 質問者はコンパイルエラーを解決するために試行錯誤していますが、エラーが取れません。
  • 質問者はRed Hatのgccを使用してコンパイルしており、関数の引数や戻り値についても説明しています。
回答を見る
  • ベストアンサー

コンパイルエラー invalid operands to binary

自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。 ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか? char *Base64n(unsigned char *buf, size_t length, size_t *outlen) { const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst         uvwxyz0123456789+/="; unsigned char *p; unsigned char *q; unsigned char a[4]; char *RtnBuf; int j=0; int cnt; RtnBuf = (char *)malloc(length+1); memset(RtnBuf, 0, length+1); p = (unsigned char*)buf; q = (unsigned char*)RtnBuf; cnt = 0; while(*p != 0) { a[0] = a[1] = a[2] = a[3] = 0; a[0] = strchr(b64, p[0]) - b64; a[1] = strchr(b64, p[1]) - b64; a[2] = strchr(b64, p[2]) - b64; a[3] = strchr(b64, p[3]) - b64; q[0] = ((a[0] << 2) | (a[1] >> 4)) & 0xff; cnt++; if (p[2] != '=') { q[1] = ((a[1] << 4) | (a[2] >> 2)) &0xff; cnt++; } if (p[3] != '=') { q[2] = ((a[2] << 6) | a[3]) & 0xff; cnt++; } p += 4; q += 3; } *outlen = cnt; return(RtnBuf); } コンパイルはRed Hatでgccを使ってコンパイルしています。 引数は第1引数がデコード対象の文字列、第2引数がデコード対象文字列長、第3引数がデコード後の文字列長で、戻り値がデコード後の文字列です。

noname#11716
noname#11716

質問者が選んだベストアンサー

  • ベストアンサー
  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

手元にgccが無いので、Windowsのbcc32でコンパイルしてみたところ、 エラーが出ずに通ってしまいました。 だから自信がないのですが…。 a[0] = strchr(b64, p[0]) - b64; を a[0] = strchr(b64, p[0]) - b64[0]; に変えてみたらどうでしょう。 "invalid operands to binary" は、たぶん、マイナスの両側で型が違っていることを 表しているのではないでしょうか。(←これも自信なし) strchr()が返すのはchar *型ですが、 b64の型は、charの配列型です。 型が違うので、コンパイラが不正と判断したのかもしれません。 とするとbcc32でなぜ通ったかが問題になるのですが…。 C言語規格でも、ポインタ同士の引き算のところは ややこしくなっています。 規格解釈の違いがあるのかもしれません。

noname#11716
質問者

お礼

おお~!! すばらしい。ご指摘どおりでした。 出力結果も問題ないようです。 二項演算の判断基準がコンパイラによって微妙にちがうようですね。 本当にありがとうございました。

関連するQ&A

  • C言語でのコンパイルエラー

    初心者です。 非常に基本的な質問かもしれませんが、 ご回答いただけたらうれしいです。 void test1(unsigned char* data) { } void test2(unsigned char** data) { } int main(void) { unsigned char data1[6]; unsigned char data2[6][6]; test1(data1); test2(data2); } としてtest1はうまくいくのに、 test2はコンパイルエラーになります。 どっちもポインタになると思うのですが…。 また、unsigned char data2[6][6]を 他の関数の引数とする場合は どうすればよろしいのでしょうか? 宜しくお願いいたします。

  • binaryに対して正規表現を適用する方法

    バイナリー配列 unsigned char buffer[BufferSize]のようなもにに対して正規表現による検索を行うにはどのようにすればよいでしょうか。正規表現には、非印刷文字も含まれます(例: \x01{5}.{10}\xFF)。宜しくお願いします。

  • SQLで以下のような構文でコンパイルエラーがでます。

    SQLで以下のような構文でコンパイルエラーがでます。 QSQL = QSQL & ",TMTNM,TO_CHAR(TMSPC,'000') AS TMSPC,HMHNM" TMSPCというフィールドを数値から文字へ変えたいのですが、 TO_CHARの引数が正しくないとでます。 どこが間違っているか教えていただけますでしょうか? TO_CHAR(TMSPC、’000’)にしても、 AS TMSPCをつけなくてもダメでした。

  • 上からよんでも下から読んでも同じか?否か?

    以下のプログラムは入力された文字をポインタを使ってpalindromeにコピーしたやつなんですが #include <stdio.h> int main ( void ){ char origin[256]; char palindrome[256]; char *p; char *q; int length = 0; printf("文字列を入力→"); scanf("%s",origin); p = origin; q = palindrome; while(*p != '\0'){ *q = *p; p++; q++; length++; } *q = '\0'; printf("length = %d\n", length); printf("入力された文字:%s",palindrome); getchar(); getchar(); return(0); } これをポインタを使って上から読んでも下から読んでも同じ(いわゆるかいぶんってやつ?)なら1を、違ったら0を返すというプログラムを組みたい場合に文字配列,及び文字配列長を引数とする関数check_anagram を使用してどのように表せるのでしょうか? とりあえずヘッダは<stdio.h>のみでできるようにしたいのですが・・・・ lengthを関数内で使ってfor文で処理? そこら辺の組み方がわからないです。

  • コンパイルエラーについて

    #include <stdio.h> int main(void){ char a[8],b[7],c[6]; printf("a[8]のアドレスは%pです。\n",&a[8]); //a[8]のメモリアドレスを表示 printf("\n"); printf("b[7]のアドレスは%pです。\n",&b[7]); //b[7]のメモリアドレスを表示 printf("\n"); printf("c[6]のアドレスは%pです。\n",&c[6]); //c[6]のメモリアドレスを表示 printf("\n"); char *c1 ="abcde"; printf("c1=%s\n",c1); //abcdeを表示 printf("c1[2]=%c\n",*(c1+2)); //先頭アドレスの2つ先のアドレスに格納されている値(c)を表示 char c2[] ="abcde"; char *pc2; printf("c2=%s\n",c2); //abcdeを表示 pc2=&c2[2]; //変数c2[2]のアドレスを格納 printf("c2[2]=%c\n",*pc2); //c2[2]アドレスに格納されている値(c)を表示 char *c="abcdefghijklmn"; char cc[]="opqrstuvwxyz"; printf("%c\n", *(c+7)); printf("%c\n", *(cc+2)); return 0; } としてコンパイルした所、 test.c: In function ‘main’: test.c:31: error: conflicting types for ‘c’ test.c:4: note: previous declaration of ‘c’ was here と出てしまいました。原因が良く分からないのですが教えて頂けますでしょうか?

  • PROCのコンパイルエラーの取り方がわかりません

    ソース自体が長いので問題となっている所だけ書きます。 情報量が少なくて申し訳ありませんが…。 VC環境です。 /* define定義 */ #define IF_ITEM_CNT 14   ・   ・   ・ /* 内部関数プロトタイプ宣言 */ int AnalyzeProc( char **pReturnString, char *pTargetString, int StrNum, char String );          /* 文字列分解処理を行う関数 */   ・   ・   ・ /* グローバル変数宣言 */ char In_Rec[ IN_FILE_MAX_LEN + 1 ]; char *w_In_Rec[ IN_ITEM_CNT + 1 ];   ・   ・    int Main{ ・   ・   ・ } int MainProc{   ・   ・ strncpy( g_dn03_rec.DN03_KISYU_MEI, sizeof( g_dn03_rec.DN03_KISYU_MEI ), w_In_Rec[ 10 ], DN03_KISYU_MEI );   ・   ・   M_Res = AnalyzeProc( &w_IN_Rec, In_Rec, IF_ITEM_CNT, ',' );   ・ addSpeace( 0, 0, DN03_KISYU_MEI_LEN, _dn03_rec.DN03_KISYU_MEI );   ・   ・ return ( TRUE ); } となっているのですが、エラーが出ます。 Warning C4047 : '関数' : 内接参照のレベルが 'char **' と 'char *(*)[15]' で異ります。 Warning C4024 : 'AnalyzeProc' この型が 1 の仮引数および実引数と異なります。 Warning C4013 : 関数 'addSpace' は定義されていません。int型の値を返す外部関数と見なします。 あとリンクのエラーで error : LNK2019 : 未解決の外部シンボル _addSpeace が関数 _MainProc で参照されました。 fatal error LNK1120: 外部参照 1 が未解決です。 というエラーが出るのですがどう直していいかわかりません。 Warning C4047も型が違うのはわかるんですがどうすればいいのか…。 Warning C4013は前にこのエラーが出たときはプロトタイプ宣言することでエラーは無くなったんですが、 今回のは違うみたいです。宣言の仕方が悪かったのかもしれませんが。

  • 配列、添え字に関するコンパイルエラーにつきまして。

    現在、arduinoで赤外線リモコンを作成しております。 ネット上の情報を参考にON/OFFのみの送信・受信はできたので、ボタンの数(mode)を21種類に増やして送信機を作成を試みております。 赤外線のON/OFFパターンの配列データが大きかったのでdata[][67]としてPROGMEM に保管し、SRAMにondata[67]として読み込もうとしています。 この状態でコンパイルすると下記のようなエラーが出てしまいます。 [mode][i][cnt]を配列のインデックス(添え字)として使っていますが、これを使用している行にこのエラーが出ます。 調べてみると添え字はintではいけないといった情報もみかけますが、data[i]のように使用されているのをよく見かけます。 データ型を変えてみたり試してみたのですが、'char[int]' や'int[char]'のように変わるだけで解決しませんでした。 このエラーに対して何か解決策があればご教授願えないでしょうか。 よろしくお願い致します。 ※エラー invalid types 'int[int]' for array subscript ※グローバル変数(PROGMEM に保存) const uint16_t data[21][67] PROGMEM = { /* 4bytes(16bits), Leader code & Customer code(CC) & Data code & ^Data code & Mode code */ /* data[0] */ {9200, 4500, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600}, /* data[1] */ {9200, 4500, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600},           ・           ・           ・ /* data[20] */ {9200, 4500, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 1650, 600, 1650, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600, 550, 600, 1650, 600}, }; ※関数 void sendOnSignal(int mode){ int ondata[67]; for (int i = 0; i < 67; i++) {ondata[i] = pgm_read_word_near(&(data[mode][i]));} int dataSize = sizeof(ondata[mode]) / sizeof(ondata[mode][0]); /* IRcodeの配列数を計算。67になるはず。 */ for(int cnt = 0; cnt < 67; cnt++) /* iIndexIRcode(現在の配列)が偶数番目ならhigh。 奇数番目ならlow。 */ { unsigned long len = ondata[mode][cnt]; /* lenに現在の配列の時間を代入。 */ unsigned long us = micros(); /* usにパルス開始時刻を記録。 */ do { /* 周波数38kHzでOn/Offするように配列の時間分点滅。 */ digitalWrite(IRLED_pin, (cnt%2) ? LOW : HIGH); /* 三項演算子[A ? B : C] (Aがtrueの場合はB,falseの場合はCを実行する) */ delayMicroseconds(8); /* キャリア周波数38kHzでON/OFFするよう時間調整 */ digitalWrite(IRLED_pin, LOW); delayMicroseconds(7); } while (long(us + len - micros()) > 0); /* 送信時間に達するまでループ */ } } /* void sendSignal終了*/

  • 警告

    char *p; const char *q; const char a='z'; const char * const pq=&a; p=q; p=pq; コンパイルは出来るのですが、警告が出ます。何故警告が出るのでしょうか?

  • freadでダンプ なぜ?

    ファイルを1バイトづつfreadで読み込んで ダンプしているのですが、なぜか16進数で"1A" (10進数で"26")の文字から先をダンプできません。 原因が良くわかりません。 どなたか、わかる方お助けください。  char buf[20];  unsigned short a;  flag = 1;  while (flag == 1){   fread(buf, sizeof(char), 1, fp_in);   a = buf[0];   printf("%02x ",a);   cnt++;   if(cnt == 16){    printf("\n");    cnt = 0;   }     :     : }

  • char型とstring型について

    char型とstring型について質問があります。 言語はC++です。 以下の関数があったとします。 void test(string a, string b string c){ 処理 } この関数を下記のように利用した場合について質問があります。 a.引数に直接文字列を挿入したケース test("aaa","bbb","ccc") b.変数に文字列を設定し、変数を引数にしたケース string a="aaa" string b="bbb" string c="ccc" test(a,b,c) (1)はコンパイルエラーになり、(2)は成功しました。 同じ様に見えるのですが、何が違うのでしょうか? また、関数の引数の型をchar*にした場合、(1)(2)のケースでコンパイルが通りました。char*型だと何が違うのでしょうか?

専門家に質問してみよう