2012-04-26 18 views
1

私はthis tutorialを使ってC++ CGIスクリプトを作っています。私は、フォームのPOSTデータを読み取るしようとすると、しかし、それはコンパイルしていない:C++ CGIスクリプト、フォームデータを読む

char* lpszContentLength = getenv("CONTENT_LENGTH"); 
    char* lpszBuffer; 
    int nContentLength = atoi(lpszContentLength); 

    lpszBuffer = malloc(lpszContentLength+1); // allocate a buffer 
    memset(lpszBuffer, 0, lpszContentLength+1); // zero it out 

    fread(lpszBuffer,1,lpszContentLength,stdin); // get data 

ここでは、コンパイラの不満です:

LN 12が「lpszBuffer」で始まるものです
cgi.cpp: In function ‘int main()’: 
cgi.cpp:12: error: invalid conversion from ‘char*’ to ‘size_t’ 
cgi.cpp:12: error: initializing argument 1 of ‘void* malloc(size_t)’ 
cgi.cpp:12: error: invalid conversion from ‘void*’ to ‘char*’ 
cgi.cpp:13: error: ‘memset’ was not declared in this scope 
cgi.cpp:15: error: invalid conversion from ‘char*’ to ‘size_t’ 
cgi.cpp:15: error: initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’ 

私はC++の新機能ですので、これを修正する方法がわからないのですが、なぜこれが起こっているのでしょうか。多分古くなったコードかもしれません...私は、喜んでPOSTリクエストからデータを読み込むための他の解決策を受け入れるでしょう。

編集: 皆さんの修正に応じてコードを更新しました。

char* lpszContentLength = getenv("CONTENT_LENGTH"); 
    char* lpszBuffer; 
    int nContentLength = atoi(lpszContentLength); 

    lpszBuffer = (char*)malloc(nContentLength+1); // allocate a buffer 
    memset(lpszBuffer, 0, nContentLength+1); // zero it out 

    fread(lpszBuffer,1,nContentLength,stdin); // get data 

しかし、私はまだATOIからセグメンテーションフォールトを取得:

==23419== Invalid read of size 1 
==23419== at 0x498DA8C: ____strtol_l_internal (strtol_l.c:298) 
==23419== by 0x498D7EF: strtol (strtol.c:110) 
==23419== by 0x498AB60: atoi (atoi.c:28) 
==23419== by 0x8048899: main (in .../cgi.cpp.cgi) 
==23419== Address 0x0 is not stack'd, malloc'd or (recently) free'd 

は、ここでの問題は何ですか? POSTが空白の場合にPOSTフォームの送信と関係があると仮定しています。

+0

malloc(lpszContentLength + 1)は 'malloc(nContentLength + 1)'であるべきですか? 'memset()'と 'fread()'にも... –

+0

このコードはC++とは関係ありません。チュートリアルは恐ろしいです。最初に、良いC++の本を見つけて、CGIで*やってみることをお勧めします。 –

+0

@KonradRudolph合意しました...私は代わりに他のものを試してみます。 – varatis

答えて

1

これはC++のタイプキャストの問題です。 lpszBufferchar*ですが、mallocvoid*を返します。だから、それをchar*にキャストする必要があります。また、真でない整数値としてchar*(lpszContentLength)を使用しようとしていることにも注意してください。これは他の関数でも更新する必要があります。これは先にatoi関数を使用して変換したものです。その値を使用してください。

のでラインは、ソースファイルの先頭に、あなたが必要#include <string.h>memsetを使用するために最後に

lpszBuffer = (char*)malloc(nContentLength+1); 

を、お読みください。

また、(スクリプトがかなりの時間実行されている場合は)良い習慣として、完了したらメモリをfreeに忘れないようにしてください。つまり、mallocで割り当てられたものは、もう使用しないときに呼び出されるfreeを持つ必要があります。あなたは、関数の最後で、関数全体を通じてlpszBufferを使用するのであれば、単純にfree(lpszBuffer);

+0

"' 'lpszBuffer'は' char * 'ですが、' malloc'は 'void *'を返しますので、 'char *'にキャストする必要があります。これは実際には真実ではありません - Cではキャストは必要なく、一般的にはお勧めしません –

+0

しかし、チュートリアルを見ると、コードは間違いなくC++です。だから、キャストが必要とされ、C++ではないと言うのは間違いです。 –

+0

これは 'C++ 'コードであることに同意しました(私はチュートリアルを見ていませんでした)。彼が投稿したコードスニペットには、「C」を示唆する詳細があります。しかし、 'C 'のようなキャストはお勧めできません。 'malloc()'の結果をキャストすることはあなた自身の "バニラ"チャンクなので完全に安全です。しかし、もっと重要なのは、このようなキャストは警告からコンパイラーを停止させ(コード化してはならない)、コードの可読性を向上させることです。 – RageD

0

error: invalid conversion from ‘char*’ to ‘size_t’

を行うこれは、この場合には、char*ある(おそらく表す文字列をlpszContentLengthを使用しようとによって引き起こされます数字)をsize_t(通常は長整数)として指定します。これを解決するには、まずlpszContentLengthを整数値に変換する必要があります。私はそれを処理する必要があるエラーを検出するので、strtol()をお勧めします。

チュートリアルを見ると、彼らは既にatoi()を使って変換しています。誤ってlpszContentLengthを使用しようとしたところでnContentLengthを使用してこのエラーを修正することもできます。彼らのコードは決してテストされてはならない。

atoi()はエラーを検出しないため、チュートリアルを完了すると、適切なエラーチェックを使用してstrtol()に変更することをおすすめします。


error: invalid conversion from ‘void*’ to ‘char*’

これは、malloc関数の戻り値に(char*)にキャストを欠落していることが原因です。 C++では、キャストが必要とされる:

lpszBuffer = (char*)malloc(convertedNumber+1); 

error: ‘memset’ was not declared in this scope

これはmemsetのためのヘッダを含めないことによって引き起こされます。 man page for memsetあなたが追加する必要がありますを示しています:それは整数型である必要がありますとき

#include <string.h> 

error: invalid conversion from ‘char*’ to ‘size_t’

error: initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’

これらは両方とも、文字の文字列であることlpszContentLengthによって引き起こされます。上記の最初のエラーを参照してください。

+0

ありがとうございました。コードを更新しましたが、まだ問題があります。上記の更新を参照してください。 – varatis

+0

私は、POSTデータが空白である(スクリプトがフォームをそれ自身に送信しているので)何かをする必要があると思います。しかしatoiを実行する前にsizeof(lpszContentLength)> 1をチェックしても、atoiはまだトリガして失敗するようです。 – varatis

+0

あなたは何を知っている、決して気にしない。このチュートリアルは恐ろしいです。ご協力いただきありがとうございます – varatis