中文字符在集合中的判断问题

自然静 2013-10-18 12:13:43

procedure TForm1.btn1Click(Sender: TObject);
var
s: string;
p: PChar;
begin
p := PChar('good. 有问题。');
while p^ <> #0 do
begin
s := '';
if p^ in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true';
mmo1.Lines.Add(p^ + Chr(9) + IntToStr(Ord(p^)) + Chr(9) + s);

inc(p);
end;
end;


结果如下:
g 103 in true
o 111 in true
o 111 in true
d 100 in true
. 46 in true
32 in true
有 26377
问 38382
题 39064
。 12290

里面的中文字符用in怎么判断不出来?请问该如何处理?
...全文
211 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
自然静 2013-10-18
  • 打赏
  • 举报
回复
引用 13 楼 wr960204 的回复:
因为集合最多256个元素.而中文属于Unicode,所以字符集合只是ANSI的. 不过可以借助子界类型. if p^ in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 case p^ of ' ', 'a'..'z', '.', '中', '文', '。': s := 'in true'; end;
谢谢wangyang4506,wr960204及其他参与各位了。
wangyang4506 2013-10-18
  • 打赏
  • 举报
回复

g	103      103	       in true
o	111      111	       in true
o	111      111	       in true
d	100      100	       in true
.	46      46	       in true
 	32      32	       in true
有	9      26377	       not in
问	238      38382	       not in
题	152      39064	       not in
。	2      12290	       not in



procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  p1: PAnsiChar;
  p2: PwideChar;
  i,j:integer;
  Str1,Str2:String;
begin
  Str1:= 'good. 有问题。';
  j:=length(Str1) ;
  for I := 1 to j do
  begin
      Str2:=Copy(Str1,i,1) ;
      p1 := PAnsiChar(Str2);
      p2 := PWideChar(Str2);
      s := '';
      if p1[0] in [' ', 'a'..'z', '.', '有', '问','题', '。'] then s := 'in true' else s := 'not in';
      memo1.Lines.Add(p2[0] + Chr(9) +IntToStr(Ord(p1[0])) +'      ' + IntToStr(Ord(p2[0])) + Chr(9) +'       '+ s);
  end;

end;
改了下代码,结果如上。之前代码的P1取值是不对的。现在我把每个字符的分别取了Ansichar 和WideChar 出来,比如: ‘有’ : AnsiChar 是09(9) 而WideChar 是6709(26377) ‘问’ : EE(238) 95EE(38382) ‘题’ : 98(152) 9898(39064) ‘。’ : 02(2) 3002(12290) 另外刚看到是有警告的: [dcc32 Warning] Unit1.pas(45): W1061 Narrowing given WideChar constant (#$6709) to AnsiChar lost information 汉字放字符集是种WideChar 到AnsiChar的强制转换,最后是不是我想的只保留低位可能不是我先前想的。 选择武稀松的方法吧,或者你要批量查特定字符什么的,用正则表达式的吧,引用下System.RegularExpressions; 。
自然静 2013-10-18
  • 打赏
  • 举报
回复
引用 11 楼 wangyang4506 的回复:
[quote=引用 10 楼 twtynk1 的回复:] 虽然没用过xe4,5等等,但是这段程序明显是有问题的! if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true' else s := 'not in'; 你看看还是你那个结果不
嗯,确实是个问题,要把S:='';要放到for循环里面。顶你下吧。[/quote] 我试了一会了,仍然没有得到正确的结果。 不知道你能验证一下吗?按着这么改的结果,还是有问题 要验证是否有‘中’‘文’这两个字, 但是我们给的字符串是'good. 有问题。' 不含中文二字的,结果还是会出现 错误的结果, 你的代码把 ’问‘判为true了 字符串转化为PWideChar和PAnsiChar,打印出来,ord值,也无关联。

P1	Ord	P2	Ord	
g	67	g	0067	
o	6F	o	006F	
o	6F	o	006F	
d	64	d	0064	
.	2E	.	002E	
 	20	 	0020	
?	D3	有	6709	
?	D0	问	95EE	in true
?	CE	题	9898	
?	CA	。	3002	
?	CC	
?	E2	
?	A1	
?	A3	
武稀松 2013-10-18
  • 打赏
  • 举报
回复
因为集合最多256个元素.而中文属于Unicode,所以字符集合只是ANSI的. 不过可以借助子界类型. if p^ in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 case p^ of ' ', 'a'..'z', '.', '中', '文', '。': s := 'in true'; end;
smhilyyan 2013-10-18
  • 打赏
  • 举报
回复
引用 10 楼 twtynk1 的回复:
[quote=引用 4 楼 wangyang4506 的回复:]
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  p1: PAnsiChar;
  p2: PwideChar;
  i,j:integer;
begin
  p1 := PAnsiChar(AnsiString('good. 有问题。'));
  p2 := PWideChar(AnsiString('good. 有问题。'));
  j:=length('good. 有问题。') ;
  s := '';
  for i:=1 to j do
  begin
      if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true';
      memo1.Lines.Add(p2[i-1] + Chr(9) + IntToStr(Ord(p2[i-1])) + Chr(9) + s);
  end;

end;
主要问题是你的p:PChar 是PWideChar 而字符集 支持的PAnsiChar ,字符集里面的汉字会被截取前一个字符,就变成你是取了双字节和单字节去判断的,所以不对。 上面的代码我也只取了一半去判断的,显示的值是双字节的。
虽然没用过xe4,5等等,但是这段程序明显是有问题的! if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true' else s := 'not in'; 你看看还是你那个结果不[/quote] 顶一个..s的值第一个是true就没变过..都没留意啊.
wangyang4506 2013-10-18
  • 打赏
  • 举报
回复
引用 10 楼 twtynk1 的回复:
虽然没用过xe4,5等等,但是这段程序明显是有问题的! if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true' else s := 'not in'; 你看看还是你那个结果不
嗯,确实是个问题,要把S:='';要放到for循环里面。顶你下吧。
Alex-16888 2013-10-18
  • 打赏
  • 举报
回复
引用 4 楼 wangyang4506 的回复:
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  p1: PAnsiChar;
  p2: PwideChar;
  i,j:integer;
begin
  p1 := PAnsiChar(AnsiString('good. 有问题。'));
  p2 := PWideChar(AnsiString('good. 有问题。'));
  j:=length('good. 有问题。') ;
  s := '';
  for i:=1 to j do
  begin
      if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true';
      memo1.Lines.Add(p2[i-1] + Chr(9) + IntToStr(Ord(p2[i-1])) + Chr(9) + s);
  end;

end;
主要问题是你的p:PChar 是PWideChar 而字符集 支持的PAnsiChar ,字符集里面的汉字会被截取前一个字符,就变成你是取了双字节和单字节去判断的,所以不对。 上面的代码我也只取了一半去判断的,显示的值是双字节的。
虽然没用过xe4,5等等,但是这段程序明显是有问题的! if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true'; 改为 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true' else s := 'not in'; 你看看还是你那个结果不
smhilyyan 2013-10-18
  • 打赏
  • 举报
回复
我擦 我还d6...
wangyang4506 2013-10-18
  • 打赏
  • 举报
回复
引用 6 楼 a215107822 的回复:
原来是我才疏学浅,sorry,我收回之前的话,受教了。。 顺便请教下?为什么我这 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then 无法编译通过??你们这么都能编译? 编译器提示 [Error] Unit1.pas(40): Incompatible types: 'Char' and 'String'
p1: PAnsiChar; p2: PwideChar; p1 := PAnsiChar(AnsiString('good. 有问题。')); p2 := PWideChar(AnsiString('good. 有问题。')); 定义有没有改好?
自然静 2013-10-18
  • 打赏
  • 举报
回复
我是xe4,楼上王哥哥是xe5,是不是版本的问题?新版本的检查问题?
引用 6 楼 a215107822 的回复:
原来是我才疏学浅,sorry,我收回之前的话,受教了。。 顺便请教下?为什么我这 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then 无法编译通过??你们这么都能编译? 编译器提示 [Error] Unit1.pas(40): Incompatible types: 'Char' and 'String'
a215107822 2013-10-18
  • 打赏
  • 举报
回复
原来是我才疏学浅,sorry,我收回之前的话,受教了。。 顺便请教下?为什么我这 if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then 无法编译通过??你们这么都能编译? 编译器提示 [Error] Unit1.pas(40): Incompatible types: 'Char' and 'String'
wangyang4506 2013-10-18
  • 打赏
  • 举报
回复
上面代码是我的XE5环境。懂了的话就给分吧~
wangyang4506 2013-10-18
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
var
s: string;
p1: PAnsiChar;
p2: PwideChar;
i,j:integer;
begin
p1 := PAnsiChar(AnsiString('good. 有问题。'));
p2 := PWideChar(AnsiString('good. 有问题。'));
j:=length('good. 有问题。') ;
s := '';
for i:=1 to j do
begin
if p1[i-1] in [' ', 'a'..'z', '.', '中', '文', '。'] then s := 'in true';
memo1.Lines.Add(p2[i-1] + Chr(9) + IntToStr(Ord(p2[i-1])) + Chr(9) + s);
end;

end;



主要问题是你的p:PChar 是PWideChar 而字符集 支持的PAnsiChar ,字符集里面的汉字会被截取前一个字符,就变成你是取了双字节和单字节去判断的,所以不对。 上面的代码我也只取了一半去判断的,显示的值是双字节的。
smhilyyan 2013-10-18
  • 打赏
  • 举报
回复
引用 1 楼 a215107822 的回复:
看完你的代码我有点。。。 in ['中','文'] 要是就能判断输入的是中文的话,估计这个开发语言应该是中国人写的 = =! 还有你确定你这段代码能运行吗? '中', '文' 这是String型,不是char型
...........你也可以的,什么叫 '中','文'是string类型??? 要判断是否中文可以通过判断Ascii码
自然静 2013-10-18
  • 打赏
  • 举报
回复
引用 1 楼 a215107822 的回复:
看完你的代码我有点。。。 in ['中','文'] 要是就能判断输入的是中文的话,估计这个开发语言应该是中国人写的 = =! 还有你确定你这段代码能运行吗? '中', '文' 这是String型,不是char型
哥哥,你能别笑得那么猥琐好伐? 程序能运行,结果我已经放上面了 按说不是有widestring,两个字节专门来装中文字的吗?不能装这么用吗? 哥哥叫我
a215107822 2013-10-18
  • 打赏
  • 举报
回复
看完你的代码我有点。。。 in ['中','文'] 要是就能判断输入的是中文的话,估计这个开发语言应该是中国人写的 = =! 还有你确定你这段代码能运行吗? '中', '文' 这是String型,不是char型

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧