みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C フォームから受け取った値をクッキーで発行

(C言語)フォームから受け取った値をクッキーで発行するにはどのようにするのでしょうか?

問題として

・フォームから値を受け取る事は出来てもクッキーが発行できない

もしくは

・フォームから値を受け取れないのにクッキーは発行できる

のどっちかしか出来ないため困りました。
どうすればフォームから受け取った値をクッキーで発行できますか?

---以下ソース---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int Deta1(char *a,int b,char *nameset[],char *valueset[]);
int Dcd(char *set,int a);

int get_cookie(char *a,int b,char *nameset2[],char *valueset2[]);
void set_cookie(char *valueset[]);

void main(void){

int i;
int a=0;

char *chr=NULL;
char *nameset[7];
char *valueset[7];
char *nameset2[7],*valueset2[7];
int b=200;
int mode=0;

char *ss=getenv("HTTP_COOKIE");

for(i=0;i<7;i++){
nameset2[i]=NULL;
valueset2[i]=NULL;
}

printf("content-type: text/html\n");
//set_cookie(valueset); //ここでset_cookie関数を呼び出せばクッキーは発行出来るけれどフォームに入力された値が入らない
printf("\n");

if(mode==0){
//省略しますがフォームで7つの項目があると思ってくださいね

if ( getenv("CONTENT_LENGTH")!=NULL ){
a = atoi( getenv("CONTENT_LENGTH") );
}

chr=(char *)malloc(a+1);
scanf("%s",chr);
chr[a] = '\0';

if (a==0){
return ;
}

printf("%s<br>",chr);

int deta1=Deta1(chr,a,nameset,valueset);
for(int i = 0;i<deta1;i++){
Dcd(nameset[i],strlen(nameset[i]));
Dcd(valueset[i],strlen(valueset[i]));
}

for(i=0;i<7;i++){
printf("%s %s<br>",nameset[i],valueset[i]);
}

//set_cookie(valueset); //ここでset_cookie関数を呼び出せばフォームが入力された値が入るけれどクッキーは発行できない

int deta2=get_cookie(ss,b,nameset2,valueset2);

for(i=0;i<7;i++){
printf("%s %s<br>\n",nameset2[i],valueset2[i]);
}


free((void *)chr);
}

else if(mode==1){
//省略
}

else{
//省略
}

}

int Deta1(char *a,int b,char *nameset[],char *valueset[]){

int i=0,cn=0;

if(a[0]==NULL){
return(-1);
}

nameset[0]=a;
while((a[++i]!=NULL)&&(i<b)){

if(a[i]=='='){
a[i]=NULL;
valueset[cn]=a+i+1;
}

else if(a[i]=='&'){
a[i]=NULL;
cn++;
nameset[cn]=a+i+1;
}
}

return cn+1;

}

int Dcd(char *set,int a){

int i,j;
char buf,*tmp;

if(a==0){
return -1;
}

tmp=(char*)malloc(a);
for(i=0,j=0;i<a;i++,j++){
if(set[i]=='+'){tmp[j]=' ';continue;}
if(set[i]!='%'){tmp[j]=set[i];continue;}
if(set[++i]>='A'){buf=set[i]-'A'+10;}
else{buf=set[i]-'0';}

buf*=16;
if(set[++i]>='A'){buf+=set[i]-'A'+10;}
else{buf+=set[i]-'0';}

tmp[j]=buf;
}

for(i=0;i<j;i++){
set[i]=tmp[i];
}
set[i]='\0';
free(tmp);

return 0;
}

int get_cookie(char *a,int b,char *nameset2[],char *valueset2[]){

int i=0,cn=0;

if(a==NULL){
return(-1);
}

while((a[++i]!=NULL)&&(i<b)){
if(a[i]=='='){
a[i]=NULL;
nameset2[0]=a+i+1;
}

if(a[i]=='-'){
a[i]=NULL;
valueset2[cn]=a+i+1;
}

else if(a[i]=='&'){
a[i]=NULL;
cn++;
nameset2[cn]=a+i+1;
}
}

return cn+1;

}


void set_cookie(char *valueset[]){
time_t timer;
struct tm *tset;
char expires[256];

char *name="sskchat";
int kikan=86400*90;
char *set[7];
int i;

for(i=0;i<7;i++){
set[i]=valueset[i];
}

for(i=0;i<7;i++){
if(set[i]==NULL){
set[i]="no";
}
}

timer = time(NULL);
timer += kikan;
tset = gmtime(&timer);

strftime(expires, 255, "%a, %d-%b-%Y %H:%M:%S GMT", tset);

printf("Set-Cookie:%s=mode-%s&name-%s&mail-%s&hp-%s&cc-%s&gyo-%s&zkou-%s; expires=%s;\n",name,set[0],set[1],set[2],set[3],set[4],set[5],set[6],expires);
}

---ソースここまで---

投稿日時 - 2012-10-25 12:49:34

QNo.7765400

暇なときに回答ください

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

> 最初に初期値を入れればいいのですか?

いいえ、何を作ろうとしているのか思い出してください。
クッキーに入れたいのは「フォームから受信した値」のはずです。
フォームからGETなりPOSTなりのメソッドで送られたデータを受信後に必要なものだけを取り出しクッキーに格納してから画面表示するのが目的(質問もそうなってませんか?)かと思いますが・・・。
最初に初期値を入れてもいれなくてもどうでもいいのですが、クッキーにセットする前に目的のデータを用意して代入しないと勝手に入ってはくれません。 最初のクッキーセットはデータ取得の前に行っていますよ。

蛇足ですが、初期値はどうでもいいと書きましたが、
Cの場合は宣言だけではメモリ上に実体が確保されるわけではないので、初期値をしっかり入れて実メモリ領域を確保しとくのは予期しないバグを生み出さないための常套手段だと思います。


> 確かにごちゃごちゃしてると言われればそんな気もします
> うまくまとめているような参考例でもなければなかなかまとめ方がよく分からんのです

ちゃんと動いて自身で全体を把握できてなおかつ人に見せるものでなければごちゃごちゃしていようといっこうにかまわないと思います。
参考例は書籍やその言語の解説サイトをみれば、人に見せるためのものがほとんどなので、ちゃんと整理されたサンプルになっているかと。

> 出力部と処理の部で分けたらまたごちゃごちゃしそうだと思いますしね

うーん・・・。ごちゃごちゃさせないために機能を分類整理するんだと思いますが・・・。

投稿日時 - 2012-10-26 16:00:54

補足

>>最初に初期値を入れてもいれなくてもどうでもいいのですが、クッキーにセットする前に目的のデータを用意して代入しないと勝手に入ってはくれません。 最初のクッキーセットはデータ取得の前に行っていますよ。

これができればできそうですがやり方がわかっていないないのでしょうね
質問内容を変えて参考になりそうなサイトを聞いてみますね
(グーグルで調べてもじぶんではなかなかみつけられなかったため)

>>うーん・・・。ごちゃごちゃさせないために機能を分類整理するんだと思いますが・・・。

おかしいですね
機能を分類すればするほどよりごちゃごちゃしていってしまいます

投稿日時 - 2012-10-29 12:59:17

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

流れを見てゆくと最初のsetcookieのパラメータvaluesetには値が代入されていないのでcookieが入らないのはそのためです。
全体的に、処理じたいがごちゃごちゃしてるので「処理部」と「出力部」に整理しましょう。デバッグ用のトラップならともかく処理しながら出力していたらどこに問題があるのかわかりにくくなります。

そして、出力はご存知かと思いますが、「httpヘッダ部」と「コンテンツ部」に分離して出力します。

概念:
 printf(httpヘッダ\n\n);
 printf(コンテンツ);

当然cookieはhttpヘッダ部内で指定します。
ヘッダ出力が終わるまで2連改行コードを出してはいけません。\n\nはヘッダの終了を意味し、残りのテキストはコンテンツと判断されます。

コンテンツはplainテキストで出力されているようですが、モダンブラウザならあまり問題はないでしょう(httpヘッダではhtml指定されているので・・・)。

投稿日時 - 2012-10-25 14:40:05

補足

<<最初のsetcookieのパラメータvaluesetには値が代入されていないのでcookieが入らないのはそのためです。

最初に初期値を入れればいいのですか?

確かにごちゃごちゃしてると言われればそんな気もします
うまくまとめているような参考例でもなければなかなかまとめ方がよく分からんのです

出力部と処理の部で分けたらまたごちゃごちゃしそうだと思いますしね

投稿日時 - 2012-10-26 10:20:42

あなたにオススメの質問