2016-09-11 3 views
-1

私たちの宿題では、ユーザーからフォームを使用して10の入力を取得するHTMLを作成する必要がありました。次に、これらの10個の入力から、10個の入力の平均を取得して結果を表示するプログラムを作成しなければなりませんでした。これは私がこれまで何をやったかである: 私たちは、最初の配列でそれらの10個の入力を保存しなければならなかったCGI-ユーザーがHTMLで入力した10個の入力の平均を取得する

CGIコード:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) 
{ 
char *data; 
int i; 
int nums[10]; 
double sum = 0.0; 
double size=0.0; 
printf("Content-type:text/html"); 
printf("<html><body>"); 

data=getenv("QUERY_STRING"); 
if(data) 
    { 
     for(i=0; i<10; i++) 
     { 
     sscanf(data,"nums[i]=%d", &nums[i]); 
     sum += nums[i]; 
     } 
    size=sum/10; 
    printf("The average is %d\n",size); 
    } 
return 0; 
} 

そしてHTML:

<html> 
<body> 
    <form action='/cgi-bin/trust.cgi'> 
     <a: input type=text value='' name=a /> 
     <b: input type=text value='' name=b /> 
     <c: input type=text value='' name=c /> 
     <d: input type=text value='' name=d /> 
     <e: input type=text value='' name=e /> 
     <f: input type=text value='' name=f /> 
     <g: input type=text value='' name=g /> 
     <h: input type=text value='' name=h /> 
     <i: input type=text value='' name=i /> 
     <j: input type=text value='' name=j /> 
     <input type=submit value='Compute'> 
    </form> 
</body> 
</html> 

QUESTION : "エラー500:サーバーエラー!スクリプトヘッダーの早すぎる終了:trust.cgi"が表示され続けます。このタイプのコードを初めてコーディングしたものです。何か助けていただければ幸いです。

編集:そのエラー500の世話をしました。しかし、今私の問題は、それが私に必要な平均に対して間違った答えを与えているということですか?どんな助け?ありがとう!

+0

'data'文字列には実際に' nums [i] = 'が含まれていますか、' nums [0] = 'のようなものですか?今あなたの 'sscanf()'は前者を探しています。また、文字列内の値を検索する場所を増やす必要があります。現在、あなたは毎回最初から始めています。 – chrisaycock

+0

chrisaycockはその部分のためのi ++ではありませんか?私は混乱してすみませます。 –

答えて

0

あなたのHTMLは実際にはHTMLではありませんので、tidyが最初です。 sscanf()とクエリ文字列を解析

<!DOCTYPE html> 
<html> 
    <head> 
    <title>Get The Average</title> 
    </head> 
    <body> 
    <form action='/cgi-bin/trust.cgi'> 
     <input type="text" value='' name="a"></br> 
     <input type="text" value='' name="b"></br> 
     <input type="text" value='' name="c"></br> 
     <input type="text" value='' name="d"></br> 
     <input type="text" value='' name="e"></br> 
     <input type="text" value='' name="f"></br> 
     <input type="text" value='' name="g"></br> 
     <input type="text" value='' name="h"></br> 
     <input type="text" value='' name="i"></br> 
     <input type="text" value='' name="j"></br> 
     <input type="submit" value='Compute'> 
    </form> 
    </body> 
</html> 

おそらく最高のアイデアではなく、あなたの教授はあなたが書いたように、同じ意見を保持しているようです。それでもそれはstrtokと確かにほんの少し良く見えるscanf()

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    char *data; 
    int i; 
    int nums[10] = {0}; 
    double sum = 0.0; 
    double size = 0.0; 
    printf("Content-type:text/html\r\n\r\n"); 
    printf("<!DOCTYPE html><html><head><title>Here's The Average</title></head><body>"); 
    // TODO: check if data is not NULL 
    data = getenv("QUERY_STRING"); 
    printf("%s</br>\n", data); 
    if (data) { 
     // That's an abomination. Obviously. 
     sscanf(data, "a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&g=%d&h=%d&i=%d&j=%d", 
      &nums[0], &nums[1], &nums[2], &nums[3], &nums[4], &nums[5], 
      &nums[6], &nums[7], &nums[8], &nums[9]); 
    for (i = 0; i < 10; i++) { 
     sum += nums[i]; 
    } 
    size = sum/10; 
    printf("The average is %f\n", size); 
    } 
    printf("</body></html>"); 
    exit(EXIT_SUCCESS); 
} 

で:だけで文字列をトークン化

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) 
{ 
    char *data; 
    char *token; 
    int i = 0; 
    int nums[10] = { 0 }; 
    double sum = 0.0; 
    double size = 0.0; 
    printf("Content-type:text/html\r\n\r\n"); 
    printf 
     ("<!DOCTYPE html><html><head><title>Here's The Average with strtok</title></head><body>"); 
    // TODO: check if data != NULL 
    data = getenv("QUERY_STRING"); 
    printf("%s</br>\n", data); 
    if (data) { 
    token = strtok(data, "&"); 
    while (token) { 
     // look for the '=' 
     while (*token != '=') { 
     token++; 
     } 
     // and skip it 
     token++; 
     nums[i++] = atoi(token); 
     // check if we have enough 
     // the constant "10" should better be #define'd 
     if (i == 10) { 
     break; 
     } 
     token = strtok(NULL, "&"); 
    } 
    for (i = 0; i < 10; i++) { 
     sum += nums[i]; 
    } 
    size = sum/10; 
    printf("The average is %f\n", size); 
    } 
    printf("</body></html>"); 
    exit(EXIT_SUCCESS); 
} 

十分ではありません、あなたは/ HTTPの文字をエスケープエスケープ解除(16進数に変換する必要があります値は%で始まります)。

+0

これは機能します!ありがとうございました! –

0

500エラーは、間違ったHTTPヘッダーが原因です。 RFC 2616によれば、HTTP応答のヘッダは、2つのCRLF改行(すなわち、"\r\n\r\n")によって応答本体から分離されるべきである。

- :(あなたが必要とするすべてのヘッダとボディの間に空白行なので、おそらく "\n\n"も動作します The CGI specification is not as strict編集)

printf("Content-Type: text/html\r\n\r\n"); 

:あなたは、第1〜第printf()ステートメントを変更することで、この問題を解決することができます

また、解析コードが完全に間違っています。一致文字列nums[i]=sscanf()に渡されるのはnumsi=にのみ一致し、クエリ文字列には表示されません。また、同じ入力文字列(data)を毎回sscanf()に渡しています。代わりにstrsep()を使用してください。

最後に、結果(double size;)を整数("%d")として印刷しようとしています。代わりに"%f"という書式指定子を使用する必要があります。

+0

1つの '\ n'が必要ですが、' \ r'や2番目の改行が意味をなさないと思います。 CR/LF改行はDOS/Windowsの典型的な伝説です。 – Olaf

+0

@Olaf 2つのCRLF改行は、[RFC 2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html)に従って、HTTPヘッダーの終わりとHTTP本体の開始をマークするために使用されます)。 –

+1

うーん、私はUnixスタイルの改行に賭けることができた。アインウェイ、私を訂正し、権威のあるリファレンスを提供してくれてありがとう。あなたの答えにそれを入れるのは良い考えです。 – Olaf

関連する問題