LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1113|回复: 13

写入问题。

[复制链接]
发表于 2004-4-27 09:30:15 | 显示全部楼层 |阅读模式
一个在线调查程序,为什么我的vote.dat里面写入的内容不正确。
出现
4294967295
4294967295
源程序如下:
界面:
[php]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> 问卷调查 </TITLE>
</HEAD>

<BODY>
<h1>问卷调查</h1>
请你选择最喜欢的网站:
<FORM METHOD = "OST" ACTION="servey.cgi">
<INPUT TYPE="radio" NAME="isp" VALUE="A" Checked>首都在线 263.net<br>
<INPUT TYPE="radio" NAME="isp" VALUE="B">广州网易 163.net<br>
<INPUT TYPE="radio" NAME="isp" VALUE="C">搜狐 SOHU.net<br>
<INPUT TYPE="radio" NAME="isp" VALUE="D">是聆听 21cn.com<br>
<INPUT TYPE="radio" NAME="isp" VALUE="E">亿唐 etang.com<br>
<INPUT TYPE="submit" VALUE="递交">
<INPUT TYPE="reset" VALUE="取消">
</FORM>
欢迎您在线查询<a href="http://127.0.0.1/perltest/sview.cgi">问卷调查结果</a>
</BODY>
</HTML>
[/php]


2.servey.cgi
[php]
#!/usr/bin/perl

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

@pairs=split(/&/, $buffer);
foreach $pair (@pairs) {
        ($name, $value)=split(/=/, $pair);
        $value=~tr/+//;
        $value=~s/%([a-f A-F 0-9][a-f A-F 0-9])/pack("C", hex($1))/eg;
        $FORM{$name} = $value;
}

$filename="vote.dat";
%NAME=("A", "首都在线", "B", "网易", "C", "搜狐", "D", "是聆听", "E", "亿唐", "E", "亿唐");
print "Content-type:text/html\n\n";
print "<HTML>";
print "<TITLE>问卷调查</TITLE>";
print "<BODY>";
print "<H1>问卷调查</H1>";
open(FILE,"<$filename")||die print"不能打开文件,请和管理员联系\n";
for ($i=0; $i<2;$i++) {
        $file[$i] = <FILE>;
        $file[$i] = ~s/\n$//;
}
close(FILE);

@item = split(/:/,$file[0]);
@vote = split(/:/,$file[1]);

for ($i=0; $i<@item+1; $i++) {
        if ($FORM{'isp'} eq $item[$i])
                {
                $vote[$i]++;
        }
}

open(FILE, ">$filename") || die "Can't open the file";
$item=join(":", @item);
$vote=join(":", @vote);
print FILE "$item\n";
print FILE "$vote\n";
close(FILE);

print "<h2>您是投票给$NAME{$FORM{'isp'}},谢谢您的支持!</h2>";
print "查询<a href=\"http://127.0.0.1/perltest/sview.cgi\">投票结果</a>";
print "</table>";
print "</body></html>";
exit;
[/php]

3.查看程序sview.cgi
[php]
#!/usr/bin/perl

$filename="vote.dat";
%NAME=("A", "首都在线", "B", "网易", "C", "搜狐", "D", "是聆听", "E", "亿唐", "E", "亿唐");
print "Content-type:text/html\n\n";
print "<HTML>";
print "<TITLE>问卷调查</TITLE>";
print "<BODY>";
print "<h1>问卷调查</h1>";
print "当前结果如下:<br>";
open(FILE, "$filename") || die "文件打开错误";

for ($i=0;$i<2 ;$i++) {
$file[$i] = <FILE>;
$file[$i]=~s/\n$//;
}
close(FILE);
@item=split(/:/,$file[0]);
@vote=split(/:/,$file[1]);
print"<table border=1>";
for ($i=0;$i<@item+1 ;$i++) {
        print "<tr><td>网站</td><td>$NAME{$item[$i]}</td><td>票数</td><td>$vote[$i]</td><tr>";
}
print "</table>";
print "</body></html>";
exit;


[/php]
发表于 2004-4-27 10:52:46 | 显示全部楼层
1、$value=~s/%([a-f A-F 0-9][a-f A-F 0-9])/pack("C", hex($1))/eg;
[a-f A-F 0-9]里不应该有空格。

2、open(FILE,"<$filename")||die print"不能打开文件,请和管理员联系\n";
从这句话看,vote.dat里应该有内容,它的内容是什么?

3、$file[$i] = ~s/n$//;
这句话应该改成$file[$i] =~ s/\n$//;
或者再规范些:chomp $file[$i];

4、for ($i=0; $i<@item+1; $i++) {
应该是$i<@item吧?
发表于 2004-4-27 11:27:35 | 显示全部楼层
我试过了,vote.dat的内容为:


  1. A:B:C:D:E
  2. 0:0:0:0:0
复制代码


按我上面说的改,就没问题。
发表于 2004-4-27 11:29:54 | 显示全部楼层
我给你改的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2004-4-27 11:33:14 | 显示全部楼层
1.写入的文件最好要锁定,防止数据腐败
2.$value=~s/%([a-f A-F 0-9][a-f A-F 0-9])/pack("C", hex($1))/eg;,其实这行是没有关系的,甚至可以拿掉,在你的程序中是不影响结果,但是不好
3.die print"不能打开文件,请和管理员联系\n" 好像不太好吧?有一点问题!
4.读文件的时候,建议使用while,不过按照Perl的座右铭,你也可以按你的写,但是不小心写错了,楼上提出你的for ($i=0; $i<@item+1; $i++) 其实是最主要的错误
5.$file[$i] = ~s/n$//; 你的意图应该是去掉换行是不是?
只要使用chomp就可以了
 楼主| 发表于 2004-4-27 12:52:45 | 显示全部楼层
谢谢各位的热心帮助!
[php]
$value=~s/%([a-f A-F 0-9][a-f A-F 0-9])/pack("C", hex($1))/eg;
[/php]
这句话是什么意思呢?
能否详说一下。
 楼主| 发表于 2004-4-27 13:19:28 | 显示全部楼层
我发现问题真的出在这一段代码中
[php]
#for ($i=0; $i<1;$i++) {
#    $file[$i] = <FILE>;
#    $file[$i] = ~s/\n$//;
#}
[/php]
tojeff兄给我指出的是正确的修改
[php]
my $line =0;
while(<FILE>) {
        chomp;
        $file[$line] = $_;
        $line++;
}
[/php]
但是我不明白上面的错误之处。
发表于 2004-4-27 13:27:37 | 显示全部楼层
最初由 edwardhayes 发表
谢谢各位的热心帮助!
[php]
$value=~s/%([a-f A-F 0-9][a-f A-F 0-9])/pack("C", hex($1))/eg;
[/php]
这句话是什么意思呢?
能否详说一下。


这个是是为了处理浏览器提交数据的编码:
比如空格在提交的时候会被编码为 %20,然后使用上面的表达式进行解码了,20可以是其他任意的16进制的数的,也就只有a-f,A-F,0-9这几种情况了,其实,小写a-f的都可以拿掉,把eg该成egi就行了,表示大小写不区分,但是,里面多了内容,也不会出错,因为[]里面的本来就是可选的,pack("C", hex($1)) 是将16进制的数转化为字符(包括中文)的一段程序
发表于 2004-4-27 13:33:12 | 显示全部楼层
for ($i=0; $i<1;$i++) {
    $file[$i] = <FILE>;
    $file[$i] = ~s/\n$//;
}
也是对的,但是可能会带来换行的问题
\n对不对?可能有 \r \n \r\n三种情况吧?各个平台是不一样的,可以使用chomp通用性好,或者使用$file[$i] =~ s/([\n\r])+$//;
 楼主| 发表于 2004-4-27 13:33:37 | 显示全部楼层
哦,明白了。
谢谢tojeff不倦的教诲!
另一个循环的问题,tojeff兄能否给点意见?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表