浙大网站上ACM的题目,我改了一个晚上还是答案错误
f you ever tried to read a html document on a Macintosh, you know how hard it is if no Netscape is installed.
Now, who can forget to install a HTML browser? This is very easy because most of the times you don't need one on a MAC because there is a Acrobate Reader which is native to MAC. But if you ever need one, what do you do?
Your task is to write a small html-browser. It should only display the content of the input-file and knows only the html commands (tags) <br> which is a linebreak and <hr> which is a horizontal ruler. Then you should treat all tabulators, spaces and newlines as one space and display the resulting text with no more than 80 characters on a line.
Input Specification
The input consists of a text you should display. This text consists of words and HTML tags separated by one or more spaces, tabulators or newlines.
A word is a sequence of letters, numbers and punctuation. For example, "abc,123" is one word, but "abc, 123" are two words, namely "abc," and "123". A word is always shorter than 81 characters and does not contain any '<' or '>'. All HTML tags are either <br> or <hr>.
Output Specification
You should display the the resulting text using this rules:
If you read a word in the input and the resulting line does not get longer than 80 chars, print it, else print it on a new line.
If you read a <br> in the input, start a new line.
If you read a <hr> in the input, start a new line unless you already are at the beginning of a line, display 80 characters of '-' and start a new line (again).
The last line is ended by a newline character.
Sample Input
Hallo, dies ist eine
ziemlich lange Zeile, die in Html
aber nicht umgebrochen wird.
<br>
Zwei <br> <br> produzieren zwei Newlines.
Es gibt auch noch das tag <hr> was einen Trenner darstellt.
Zwei <hr> <hr> produzieren zwei Horizontal Rulers.
Achtung mehrere Leerzeichen irritieren
Html genauso wenig wie
mehrere Leerzeilen.
Sample Output
Hallo, dies ist eine ziemlich lange Zeile, die in Html aber nicht umgebrochen
wird.
Zwei
produzieren zwei Newlines. Es gibt auch noch das tag
--------------------------------------------------------------------------------
was einen Trenner darstellt. Zwei
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
produzieren zwei Horizontal Rulers. Achtung mehrere Leerzeichen irritieren Html
genauso wenig wie mehrere Leerzeilen.
output那里要求最后以一个newline结尾
我的代码是
int main()
{ char c;
while ( (c=getchar()) != EOF ){
//对输入的处理...
}
printf("\n");
}
但是它读完了输入以后还是不断地getchar();
不会跳出while执行下面的printf"(\n");
我想了一个通宵没搞好
请高手不吝指点
不够分可以再加.
问题点数:0、回复次数:25Top
1 楼Igj1012(进口超人:国产超人,你把洗脚水给我倒了~~)回复于 2005-04-14 10:22:10 得分 0
输入完按Ctrl+Z试试Top
2 楼zhangfjj(小张)回复于 2005-04-14 10:38:01 得分 0
楼上的回答应该是对的
循环结束的条件EOF,
是按Ctrl+Z或F6来输入!Top
3 楼C_projecting(逝者如C)回复于 2005-04-14 11:00:17 得分 0
问题是放到浙大网站上测试,输入的东西不是由我决定的Top
4 楼zhang_jiang(Solar)回复于 2005-04-14 11:04:24 得分 0
EOF是也int型, 为0xffffffff(不同机器不同位数)
但是你的c为char型, 比较时应该是无符号扩展为:0x000000xx
所以, 不可能相等...
建议用int c;Top
5 楼kobefly(科比--网络学习中)回复于 2005-04-14 11:09:55 得分 0
恩
是的
应该用int
我觉得Top
6 楼sdp(雨尘)回复于 2005-04-14 11:25:34 得分 0
用while(scanf("%c",&c) != EOF)
Top
7 楼pcboyxhy(-273.15℃)回复于 2005-04-14 11:31:31 得分 0
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string word;
int word_l,poi;
int main()
{
poi=0;word="";
while(cin>>word)
{
word_l=word.length();
if(word=="<br>"){cout<<endl;poi=0;}
if(word=="<hr>")
{
if(poi!=0)cout<<endl;
for(int i=1; i<=80; i++)
cout<<"-";
cout<<endl;
poi=0;
}
if(word!="<br>" && word!="<hr>")
{
if(poi==0){cout<<word;poi=word_l;}
else if(poi>0 && poi+word_l+1<=80){cout<<" "<<word;poi+=word_l+1;}
else if(poi>0 && poi+word_l+1> 80){cout<<endl<<word;poi=word_l;}
}
}
cout<<endl;
}
这个是AC了的
Top
8 楼zhang_jiang(Solar)回复于 2005-04-14 11:41:46 得分 0
说的不够详细, 再详细点. ;-)
当遇到文件末尾时, getchar()返回EOF(0xffffffff), 当赋值给c时,
int被砍断, c==0xff;
然后, 又要与int型的EOF比较, c零扩展为0x000000ff, 则无限循环...Top
9 楼zhousqy(标准C匪徒)(甩拉,甩拉)回复于 2005-04-14 15:44:50 得分 0
int c;Top
10 楼jacksonwj(缺水的海豚)回复于 2005-04-14 18:42:05 得分 0
c 零扩展为0x000000ff
用 int c; 应该就可以解决问题了~~~Top
11 楼ljq14(冷爱)回复于 2005-04-14 19:10:26 得分 0
upTop
12 楼zhangfjj(小张)回复于 2005-04-14 20:23:19 得分 0
如果是象楼上几位所说的那样的话,这个问题在《C陷阱与缺陷》一书中专门进行了讨论。
绝大多数编译器,不会采用零扩展而是采用符号扩展。
我想,楼主是疑问怎么输入EOF,无法输入EOF就只能陷入“死循环”。
=====================
在该书中举的例子
#include <stdio.h>
main()
{
char c;
while((c=getchar())!=EOF)
putchar();
}
有两种可能,一是某些合法输入被”截断“后可能使得C的值与EOF相同, 另一种可能是,C根本不可能取到
EOF这个值。对于前一种,程序将在复制文件的中途被终止,后一种情况,程序将陷入死循环。
实际上,还有可能存在第三种情况,程序表面工作正常,但完全是因为巧合,尽管getchar()的返回结果
在赋给char类型变量c时会发生”截断“,尽管while语句中比较运算的操作数不是getchar()的返回值,而是被截
断的值C,然而令人惊讶的是许多编译器对上述表达式的实现并不正确。这些编译器确实对函数getchar()的返回值
作了”截断“处理,并把低字节部分赋给了变量c,但它们在比较表达式中并不是比较c和EOF,而是比较getchar()
函数的返回值与EOF!编译器如果采用的是这种做法,上面的例子看上去就能”正常“工作了
=====================
上面这段话摘自《C陷阱与缺陷》,讨论好象是关于文件的读写,不过对这个例子也是适用的!
Top
13 楼zhang_jiang(Solar)回复于 2005-04-14 21:22:46 得分 0
zhangfjj(小张(张三的张,不小的小))说的是对的, 高手!!!
我反汇编了一下:
while((c=fgetc(fp))!=EOF)
==>
subl $12, %esp
pushl -8(%ebp)
call fgetc
addl $16, %esp
movb %al, -1(%ebp)
movb -1(%ebp), %al
cmpb $-1, %al /* !!! 竟然直接用-1来比较 */Top
14 楼lezi1022(doyouknowdk)回复于 2005-04-14 22:34:03 得分 0
学习Top
15 楼CJLL0218(CJ_C\C++)回复于 2005-04-14 23:13:40 得分 0
我的老师说过:非‘零’为真!!
我觉得,跟EOF比较以后取反的话,永远都是‘真’ 所以是死循环啊!
我的老师还说过,在C里,int就是char ,char就是int!
谢谢~~
Top
16 楼ljq14(冷爱)回复于 2005-04-14 23:20:40 得分 0
学习~~Top
17 楼ljq14(冷爱)回复于 2005-04-14 23:21:51 得分 0
我楼上的兄弟强~~~~
呵呵Top
18 楼Kid4you(Kid4you)回复于 2005-04-15 01:49:50 得分 0
ZJU那题目做过,不过小弟都是用c++写的。Top
19 楼aladar(深蓝)回复于 2005-04-15 10:13:27 得分 0
那题我一次就AC了。。。没挑战
楼主测试时把输入放到文件里,然后 xxx < in.txt 这样EOF就能处理
还有楼主的处理文件结尾的方法是正确的。不用改
Top
20 楼liujinxing(☆☆)回复于 2005-04-15 10:38:38 得分 0
EOF需要ctrl+z或者f6的吧Top
21 楼C_projecting(逝者如C)回复于 2005-04-15 13:40:21 得分 0
我想问ACM测试时的输入算是键盘输入还是文件输入?Top
22 楼zhang_jiang(Solar)回复于 2005-04-15 14:16:08 得分 0
一般是用文件输入输出的呀.
没有见过键盘输入.Top
23 楼aladar(深蓝)回复于 2005-04-15 16:04:35 得分 0
键盘也是文件啊,只是是特殊的文件罢了
看库的代码就会发现 scanf就是fscanf在文件名是stdin时的特例
printf->fprintf(stdout...
等等都是Top
24 楼aladar(深蓝)回复于 2005-04-15 16:05:01 得分 0
不是文件名,是文件描述符:DTop
25 楼C_projecting(逝者如C)回复于 2005-04-15 22:19:36 得分 0
键盘输入只能输入一个"回车"而且之后会中止
文件输入可以有多个回车啊~而且到EOF才终止Top




