你好
我有这个任务只打印C ++字符串中的字母。它适用于大多数输入,但当输入中存在[
和]
时,它们也会被打印出来。
#include <iostream>
#include <string>
using namespace std;
int main()
{
string input = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG]";
for(int i=0;i<input.size();i++)
{
if(input[i] >='A' && input[i] <= 'z')
//if(isalpha(input[i]))
cout<<input[i];
}
cout<<endl;
return 0;
}
问题出在这里:
if(input[i] >='A' && input[i] <= 'z')
^^^ ^^^
您正在使用大写'A'
和小写'z'
。
范围A-z
与A-Z
+ a-z
不同。
Z
的ASCII值是90
,而a
的ASCII值是97
。
在他们之间有6个其他字符,你正在考虑作为字母表。
ASCII value Character
------------------------
90 Z
91 [ \
92 \ \
93 ] \ your range A-z includes these.
94 ^ /
95 _ /
96 ` /
97 a
要仅允许使用大写和小写字母,您应该使用:
if( (input[i] >='A' && input[i] <= 'Z') || (input[i] >='a' && input[i] <= 'z') )
或者甚至更好地使用isalpa
:
if(isalpha(input[i]))
这是因为A-z范围内有一些特殊字符。如果要过滤掉[和]等特殊字符,则需要单独使用A-Z范围,然后单独使用a-z范围
你不需要这一行:
if(input[i] >='A' && input[i] <= 'z')
你的程序工作正常..
isalpha
应该在方括号上返回0,因为它是由标准(C ++03§7.4.1.2.2)定义的
isupper
或islower
为true的任何字符的测试,或任何字符集特定的字母字符集之一的字符,其中iscntrl
,isdigit
,ispunct
或isspace
都不为真。在“C”语言环境中,isalpha
仅对isupper
或islower
为true的字符返回true。
它们不应被视为大写或小写字符。
另一方面,你的
if(input[i] >='A' && input[i] <= 'z')
这是错误的,因为['A','z']范围通常还包括非字母字符,特别是标准ASCII中的字符[ \ ] ^ _ `
。
因此,您应该将支票分成两部分(检查字符是否在范围['A'
,'Z'
]或['a'
,'z'
])或者只是使用isalpha
而忘记这些东西。
顺便说一下,该标准甚至没有要求['A'
,'Z'
]和['a'
,'z'
]范围必须是连续的(它只能保证['0'
,'9'
]的连续性,并且事实上是原始的EBCDIC代码页是一个真正的混乱处理,因为要检查一个字符是否按字母顺序排列,你无法检查字符是否在这些范围内。因此,要严格标准,你甚至不能指望
if((input[i] >='A' && input[i] <= 'Z') || (input[i] >='a' && input[i] <= 'z'))
将按预期工作。
简而言之:如果不仅仅是作业,请使用isalpha
,它可以保证您的平台使用任何奇怪的代码页。
或者,#include<cctype>
并使用std::isalpha(input[i])