フォームデータをLong型に変換できないエラーが発生する理由

このQ&Aのポイント
  • フォームデータをLong型に変換する際にエラーが発生しています。
  • プログラムの実行中にOK1までは正常に表示されるが、OK2の直前でエラーが発生しています。
  • C_LENのatol関数が正しく動作していない可能性があり、原因は不明です。
回答を見る
  • ベストアンサー

受け取ったフォームデータをLong型にできないのですが・・・。

お世話になります。 まず、次のプログラムを見てください。 簡略化しています。 int main(void) { char *C_LEN; long length; C_LEN=(char*)getenv("CONTENT_LENGTH"); printf("OK1\n");getch(); length=atol(C_LEN); printf("OK2\n");getch(); return 0; } CONTENT_LENGTH内にはフォームからのデータが入っているとしてください。 これを実行すると、OK1まではちゃんと表示されるのですが、 OK2の表示される直前でエラーがでてしまいます。 C_LENのatolがうまくいけてないようなのですが、 どのサイトを見てもこのような書き方がされていて、 なぜエラーがでてくるのかが見当付きません。 お手数ですが、原因を教えていただけませんでしょうか。 ちなみに、コンパイル・ビルドは、 最初Borland C++ Compilerでやってみてうまくいかなかったので、 Visual C++でもやってみたのですが、それでもうまくいきませんでした。

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

  • ベストアンサー
  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.1

エラーを返すのか死んでいるのかにもよりますが… atol()がエラーを返すことでプログラムがとまることはありえないので「死んでいる」と判断します。 そうなると、C_LENがNULLになっていてatol()に入ったとたんに死ぬという状況が一番ありえる。 printf("%p", getenv("CONTENT_LENGTH") ; はどうなりますか?

Wingard
質問者

お礼

ありがとうございました、できました♪ おっしゃったとおり、CONTENT_LENGTHの中身がNULLでした・・・・・・。 てっきり入っていると思い込んでいました。 なるほど、NULLだとatoiは使えないんですね。 ありがとうございました♪

関連するQ&A

  • CGIで送受信するプログラムの作り方

    入力フォームを返すのとフォームからのPOSTとGETを受け取って処理する、 同一のスクリプトを、CGI、C言語で作成致しましたが、 上手く動作していません。(白紙のページが表示されるだけでした。) getenv("REQUEST_METHOD");がNULLだった場合に本来表示されるハズのページが表示されるはずで、これが出ないという事は、getenv("REQUEST_METHOD");がNULLでなく、うまく動作していないのでは? こう考え、getenv("REQUEST_METHOD");の中身を表示させた所、GET と表示されました。 何も送信していないのに、GETと判断されているのは何故でしょうか? また、正しい動作をするプログラムをご提示頂けますと助かります。 /* form2.c */ #include <stdio.h> #include <stdlib.h> int main(void) { int len; char *clen; char *data,*method,*qs; printf("Content-type: text/html\n\n"); printf("<html><head></head><body>\n"); method = getenv("REQUEST_METHOD"); printf("%s\n", method); if(method == NULL){ printf("Content-type: text/html\n\n"); printf("<html>\n"); printf("<head>\n"); printf("<title>form test page</title>\n"); printf("</head>\n"); printf("<body>\n"); printf("<form method=\"post\" action=\"form2.cgi\">\n"); printf("<input type=\"text\" name=\"fieldname\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname2\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname3\" size=\"50\"><br>\n"); printf("<input type=\"submit\" value=\"書き込み\">\n"); printf("</form>\n"); printf("<form method=\"get\" action=\"form2.cgi\">\n"); printf("<input type=\"text\" name=\"fieldname\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname2\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname3\" size=\"50\"><br>\n"); printf("<input type=\"submit\" value=\"書き込み\">\n"); printf("</form>\n"); printf("</body>\n"); printf("</html>\n"); exit(0); } //POST else if(!strcmp(method, "POST")){ clen = getenv("CONTENT_LENGTH"); if(clen == NULL){ exit(0); } len = atol(clen); data = malloc(len+1); scanf("%s",data); data[len] = '\0'; printf("Content-type: text/html\n\n"); printf("<html><head></head><body>\n"); printf("%s<br>\n", data); printf("</body></html>\n"); } //GET else if(!strcmp(method, "GET")){ qs = getenv("QUERY_STRING"); printf("Content-type: text/html\n\n"); printf("<html><head></head><body>\n"); printf("%s<br>\n", qs); printf("</body></html>\n"); } printf("</body></html>\n"); } 宜しくお願いいたします。

    • ベストアンサー
    • CGI
  • CGIでPOSTで送受信するプログラムの作り方

    こんにちは、C言語でCGIを作成していて疑問に思ったのですが、 POSTメソッドで送られてきたデータを解析する際には、POSTで送信するプログラムと、 POSTを受信するプログラムとに必ず分けてある様に感じられました。 これらを1つにまとめて送受信する事は出来ないのでしょうか? 例えば、以下の様なプログラムを組んだとします。 /* form.c */ #include <stdio.h> int main(void) { printf("Content-type: text/html\n\n"); printf("<html>\n"); printf("<head>\n"); printf("<title>form test page</title>\n"); printf("</head>\n"); printf("<body>\n"); printf("<form method=\"post\" action=\"form2.cgi\">\n"); printf("<input type=\"text\" name=\"fieldname\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname2\" size=\"40\"><br>\n"); printf("<input type=\"text\" name=\"fieldname3\" size=\"50\"><br>\n"); printf("<input type=\"submit\" value=\"書き込み\">\n"); printf("</form>\n"); printf("</body>\n"); printf("</html>\n"); } /*以下、受信プログラム*/ /* form2.c */ #include <stdio.h> #include <stdlib.h> int main(void) { int len; char *clen; char *data; clen = getenv("CONTENT_LENGTH"); if(clen == NULL){ printf("no contents.\n"); exit(1); } len = atol(clen); data = malloc(len+1); scanf("%s",data); data[len] = '\0'; printf("Content-type: text/html\n\n"); printf("<html><head></head><body>\n"); printf("%s<br>\n", data); printf("</body></html>\n"); } 上記2つのプログラムを1つに統合して、 送受信を1つのプログラムで行うという事は出来ないのでしょうか? よろしくお願いします。

    • ベストアンサー
    • CGI
  • 文字の表示なのですが

    int i; int len = length[n]; for( i = 0; i <= len; i++ ){ printf("%c ", path[n][i] + 'A' ); } printf("%c\n", goal + 'A' ); } このままだと、 ABCDEFGHIJ・・・の順に表示されてしまいます。 SABCDEFGHI・・・と表示したいのですがどのようにすればいいのでしょうか。

  • コードのどこが間違っているのかを教えてください。

    ある文字を入力し、それをカンマ区切りして3つに分け、その3つの最大値を表示するプログラムを入力したいです。ただし、条件として、上限の桁数5を越える、文字か数字化の判定を行い、文字が1つでも混ざっている際はエラー表記され再度入力、さらに終了判断を行う際も、あくまで「y」「n」と入力したときのみが正常であり、複数文字を入力する際は、エラー表記され、再度入力という形をとりたいです。 フローを書きながら、サブ関数も使い、LINUXで以下のように書いてみました。 ただ、これだと /*-----------------------------------------*/ /tmp/ccKMOmJN.o: In function `word_judge': kadai6.c:(.text+0x4b2): undefined reference to `isdigits' collect2: ld はステータス 1 で終了しました /*-----------------------------------------*/ となってしまいました。 どのようなコードに直せばいいのでしょうか? すごく長いですが、わかりやすく解説してくださると、とても助かります。 あと、fgets関数やsscanf、getchar関数など、ネット上のサンプルを参照して、使っただけなので、もしかしたら間違ってるかもしれません。 そこについても、教えてくださると、とてもうれしいです。 /* ソースコード */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #define LIMIT (5) #define NULLB '\0' #define ECOUNT (20) #define EWORD (2) int word_judge(char array[]); void digits_judge(int a_len , int b_len , int c_len) ; int main(int argc , char *argv[]) { int number_a ; int number_b ; int number_c ; int input_len ; int a_len ; int b_len ; int c_len ; int end_len ; char input[ECOUNT] ; char a[ECOUNT] ; char b[ECOUNT] ; char c[ECOUNT] ; char array[ECOUNT] ; char end[EWORD] ; end[0] = 'n' ; while( end[0] == 'n' ) { while(1) { number_a = 0 ; number_b = 0 ; number_c = 0 ; input_len = 0 ; a_len = 0 ; b_len = 0 ; c_len = 0 ; end_len = 0 ; memset(input , NULLB , sizeof(char) *ECOUNT) ; memset(a , NULLB , sizeof(char) *ECOUNT) ; memset(b , NULLB , sizeof(char) *ECOUNT) ; memset(c , NULLB , sizeof(char) *ECOUNT) ; memset(end , NULLB , sizeof(char) *EWORD) ; printf("a , b , c ?:") ; fgets(input , ECOUNT , stdin); input_len = strlen(input); if( input_len < ECOUNT-1 ) { sscanf(input , "%[^,] , %[^,], %s" , a , b , c); if(a[0] != NULLB && a[0] != NULLB && c[0] != NULLB) { if(word_judge(a) != 0 && word_judge(b) != 0 && word_judge(c) != 0 ) { a_len = strlen(a) ; b_len = strlen(b) ; c_len = strlen(c) ; if(a_len >= LIMIT || b_len >= LIMIT || c_len >= LIMIT) { digits_judge(a_len , b_len , c_len) ; } else { number_a = strtol(a , NULL , 10) ; number_b = strtol(b , NULL , 10) ; number_c = strtol(c , NULL , 10) ; printf("最大値:") ; if(number_a > number_b && number_a > number_c) { printf("%d\n", a); } else { if(number_b >number_a && number_b > number_c) { printf("%d\n", b) ; } else { printf("%d\n", c) ; } } break ; } } else { printf("文字が混ざっています。\n") ; } } else { printf("正しく入力して下さい。\n") ; } } else { if(input[ECOUNT] == '\n') { } else { while(getchar() != '\n'); } printf("入力数が多いです。\n"); } } while(1) { int end_len ; char end[EWORD] ; end_len = 0 ; memset(end , NULLB , sizeof(char) *EWORD) ; printf("終了しますか? y/n: "); fgets(end , EWORD , stdin); end_len = strlen(end); printf("\n"); if(end_len == EWORD) { if(end[0] != 'y' && end[0] != 'n') { printf("y or nを入力して下さい。\n"); } else { break ; } } else { if(input[ECOUNT] == '\n') { } else { while(getchar() != '\n'); } printf("入力が間違っています。y or n を入力しなおしてください。\n"); } } } return 0 ; } int word_judge(char array[ ]) { int array_len ; int i ; int tmp ; int r_value ; tmp = 0; r_value = 0 ; for(i=0 ; i< array_len ; i++) { tmp = isdigits(array[i]) ; if(tmp != 0) { r_value = 1; } else { r_value = 0; break ; } } return r_value ; } void digits_judge(int a_len , int b_len , int c_len) { int a ; int b ; int c ; a = 0 ; b = 0 ; c = 0 ; a_len = 0 ; b_len = 0 ; c_len = 0 ; if(a_len >= LIMIT) { a = 1 ; } else { } if(b_len >= LIMIT) { b = 10 ; } else { } if(c_len >= LIMIT) { c = 100 ; } else { } switch(a + b + c) { case 111 : printf("aとbとcの桁が多いです。\n"); break; case 11 : printf("aとbの桁が多いです。\n"); break; case 110 : printf("bとcの桁が多いです。\n"); break; case 101 : printf("cとaの桁が多いです。\n"); break; case 1 : printf("aの桁が多いです。\n"); break; case 10 : printf("bの桁が多いです。\n"); break; case 100 : printf("cの桁が多いです。\n"); break; } }

  • 下のコードの修正をお願いします。

    終了処理、バッファのクリアなど、ほとんどの処理は出来たのですが、唯一a,b,cの入力数が上限の桁数LIMITをオーバーしてしまった場合に本来エラーが表示されなければならないのにそのまま正常処理で最大値が出力されてしまいます。つまり、サブ関数void disp_errorでの処理がmain関数で実行されません。 どこを直せばいいのでしょうか? #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #define LIMIT (5) #define NULLB '\0' #define ECOUNT (3*LIMIT + 4) #define EWORD (3) #define NORMAL (0) #define ABNORMAL (-1) #define LF '\n' int word_judge(char array[]); void disp_error(int x_len , int y_len , int z_len) ; int main(int argc , char *argv[]) { int number_a ; int number_b ; int number_c ; int input_len ; int a_len ; int b_len ; int c_len ; int end_len ; int max ; char input[ECOUNT+1] ; char a[ECOUNT+1] ; char b[ECOUNT+1] ; char c[ECOUNT+1] ; char array[ECOUNT+1] ; char end[EWORD+1] ; end[0] = 'n' ; while(end[0] == 'n' ) { while(1) { number_a = 0 ; number_b = 0 ; number_c = 0 ; input_len = 0 ; a_len = 0 ; b_len = 0 ; c_len = 0 ; end_len = 0 ; max = 0; memset(input , NULLB , sizeof(char) *ECOUNT+1) ; memset(a , NULLB , sizeof(char) *ECOUNT+1) ; memset(b , NULLB , sizeof(char) *ECOUNT+1) ; memset(c , NULLB , sizeof(char) *ECOUNT+1) ; memset(end , NULLB , sizeof(char) *EWORD+1) ; printf("a,b,c ?:") ; fgets(input , ECOUNT+1 , stdin) ; input_len = strlen(input) ; if(input_len <ECOUNT) { a_len = strlen(a) ; b_len = strlen(b) ; c_len = strlen(c) ; sscanf(input , "%[^,], %[^,], %s" , a , b , c) ; if(a[0] != NULLB && b[0] != NULLB && c[0] != NULLB) { if(word_judge(a) == NORMAL && word_judge(b) == NORMAL && word_judge(c) == NORMAL) { if(a_len > LIMIT || b_len > LIMIT || c_len > LIMIT) { disp_error(a_len , b_len , c_len) ; } else { number_a = strtol(a , NULL , 10) ; number_b = strtol(b , NULL , 10) ; number_c = strtol(c , NULL , 10) ; max = number_a ; printf("最大値:") ; if(number_b > number_a) { max = number_b ; if(number_c > number_b) { max = number_c ; } } else { if(number_c > number_a) { max = number_c ; } } printf("%d\n" , max) ; break ; } } else { printf("文字が混ざっています。 \n") ; } } else { printf("正しく、入力をしてください。\n") ; } } else { if(input[ECOUNT-1] == LF) { } else { /* バッファのクリアを行う */ while(getchar() != LF); } printf("入力数が多いです。\n") ; } } while(1) { printf("終了しますか? y/n:" ); fgets(end , EWORD+1 , stdin ) ; end_len = strlen(end) ; if(end_len < 3) { if(end[0] != 'y' && end[0] != 'n') { printf("y or nを入力して下さい。\n") ; } else { break ; } } else { if(end[EWORD-1] == LF) { } else { while(getchar() != LF) ; } printf("入力が間違っています。y or nを入力しなおしてください。\n") ; } } } return 0 ; } int word_judge(char array[]) { int array_len ; int i ; int sub_number ; int r_value ; sub_number = 0 ; r_value = NORMAL ; array_len = strlen(array) ; for(i=0 ; i<array_len ; i++) { sub_number = isdigit(array[i]) ; if(sub_number != 0) { r_value = NORMAL ; } else { r_value = ABNORMAL ; break ; } } return r_value ; } void disp_error(int x_len, int y_len , int z_len) { int fc ; fc = 0 ; if(x_len > LIMIT) { fc += 1 ; } if(y_len > LIMIT) { fc += 10 ; } if(z_len > LIMIT) { fc += 100 ; } switch(fc) { case 11 : printf("aとbの桁が多いです。 \n") ; break ; case 110 : printf("bとcの桁が多いです。 \n") ; break ; case 101 : printf("aとcの桁が多いです。 \n") ; break ; case 1 : printf("aの桁が多いです。 \n") ; break ; case 10 : printf("bの桁が多いです。 \n") ; break ; case 100 : printf("cの桁が多いです。 \n") ; break ; } }

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込

    ネットで落ちていた「Excelで作ったデータ(CSVファイル)の読み込みプログラム」をそのままコンパイルして実行しようと思ったのですが、 sample.c: In function 'main': sample2.c:9: warning: return type of 'main' is not 'int' と、表示されてしまいます。 プログラミング初心者なので、どこが間違っているのかわかりません。 回答またはアドバイスの程、よろしくお願いいたします。 ネットで落ちていたプログラムを以下に記載します。 sample2.c #include <stdio.h> #define MAX_ITEM_SIZE 100 #define MAX_LINE_SIZE 1024 char *GetCSVItem(char *wp, char *buff, int size); void main(int argc, char *argv[]) { FILE *fp; char buff[MAX_LINE_SIZE], *wp, item[3][MAX_ITEM_SIZE]; int i1, len; if(argc != 2){ printf("コマンドの入力形式が間違っています.\n"); return; } fp = fopen(argv[1], "r"); if(fp == NULL){ printf("ファイルがオープンできません[%s].\n", argv[1]); return; } for(;;){ if(fgets(buff, MAX_LINE_SIZE, fp) == NULL) break; len = strlen(buff); if(len == 0 || buff[len-1] != '\n'){ if(feof(fp) == 0){ printf("データが不正です[%s].\n", buff); return; } } buff[len-1] = '\0'; wp = buff; if((wp = GetCSVItem(wp, item[0], MAX_ITEM_SIZE)) == NULL){ printf("エラー(1)\n"); break; } if((wp = GetCSVItem(wp, item[1], MAX_ITEM_SIZE)) == NULL){ printf("エラー(2)\n"); break; } if((wp = GetCSVItem(wp, item[2], MAX_ITEM_SIZE)) == NULL){ printf("エラー(3)\n"); break; } if(*wp != '\0'){ printf("エラー(4)\n"); break; } for(i1 = 0; i1 < 3; i1++){ printf("%d:%s\n", i1+1, item[i1]); } } fclose(fp); } char *GetCSVItem(char *wp, char *buff, int size) { int i1; buff[0] = '\0'; while(*wp == ' ' || *wp == '\t') wp++; if(*wp == '\0'){ return(NULL); } for(i1 = 0; i1 < MAX_ITEM_SIZE; i1++, wp++){ if(i1 >= size) return(NULL); buff[i1] = *wp; if(*wp == '\0'){ buff[i1] = '\0'; return(wp); } if(*wp == ','){ wp++; buff[i1] = '\0'; break; } } return(wp); }

  • C言語プログラム

    したのプログラムでgetch()の代わりにscanf()を使って、入力した数が負なら終了、正なら"次の数を入力してください"と表示してループを続けるプログラムを作りたいのですが、どこを変えればよいのですか? #include<stdio.h> #include<conio.h> void main() { int i=1,sum=0; char c='m'; while(c!='e')//eでない限りwhileループを実行する { sum=sum+i; printf("\n1 kara %d madewo tasuto %d desu.\n",i,sum); i++; printf("nanikakeywo oshitekudasai.owaru tokiha 'e'\n"); c=getch(); } printf("loopwo nukemashita\n"); getch(); }

  • c言語

    #include<stdio.h> #include<conio.h> void main() { int i=1,sum=0; char c=\'m\'; while(c!=\'e\')//eでない限りwhileループを実行する { sum=sum+i; printf(\"\\n1 kara %d madewo tasuto %d desu.\\n\",i,sum); i++; printf(\"nanikakeywo oshitekudasai.owaru tokiha \'e\'\\n\"); c=getch(); } printf(\"loopwo nukemashita\\n\"); getch(); } while(c!=\'e\')をwhile(c>0)にして実行したい場合はcharをintにかえて、scanfを使わなければならないのはわかりますが、どこを変えればよいか分かりません。ちなみに、while(c>0)に変えた場合に、正の数を入力した後に、「次の数を入力してください」という文を表示してからくりかえす方法をおしえてください。

  • PathIsDirectoryを使って

    #include <windows.h> #include <stdio.h> //#include <Dbghelp.h> #include <shlwapi.h> void main(void) { char *Path = "c:\\windows\\system32\\"; if(PathIsDirectory(Path)) printf("'%s'は正しいディレクトリである。\n",Path); else printf("'%s'は正しいディレクトリでない。\n",Path); } をボーランドC++5.5でコンパイルすると Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.cpp: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル 'PathIsDirectoryA' が未解決(C:\BORLAND\test.OBJ が参照) というエラーがでました。 どうしたらいいのでしょうか?

専門家に質問してみよう