在C中,我如何检查数组中只有ASCII定义的字母而不使用大量的If语句?



我试图确保在命令行输入的数组只有字母,大写和小写。

如果它是数字或其他任何东西,那么我想结束程序。

现在,我知道我可以用大量的if语句来做这个:

如果在this和that之间

else this and that.

但是我想尝试学习一种更有效的方法来做到这一点,因为我确定有一个for循环我还没有弄清楚。我问是因为我想让用户输入一个长度为x的键。为了达到期望/所需的字符串长度,我使用了类似的方法,即多个if else语句。

#include <stdio.h>
#include <string.h>

int validate_key(int argc, string argv[]);
int main(int argc, string argv[])
{
string input;
int score;
score = validate_key(argc, argv);
if (score == 0)
{
// if required key is valid, next function of program here

}
}
int validate_key(int argc, string argv[])
{
//KEY VALIDATION 
int l = 0; //initialize length variable
string s;
//To make sure that the string entered at command line is the required 26 characters, 
//and that it isnt empty
if (argc == 2) //make sure there are no spaces in the entered string
{
s = argv[1];     //assign key to string s
l = strlen(s);   //check length of KEY
}
//check to see string isnt NULL / empty
if (argc !=0 && l == 26) 
{

//make a for loop that scans the array making sure it is between two values? 
//attempting to check argv to make sure it is a lowercase and or uppercase string 
for (int i = 0; i < l; i++)
{
int charValue = argv[1][i];
if ( ( charValue > 64 && charValue < 91 ) || ( charValue > 96 && charValue < 123 ) )
{
printf("%cn", charValue); //to show me that it made it into the if statement
}
else
return 1;
}

return 0;
}
else if (l <= 25 && l >= 1) //entered key is too small
{
printf("Please Enter 26 Letter Key n");
printf("value of l: %dn", l);
return 1;
}
else //entered key is empty
{
//printf("value of l: %dn", l);
printf("missing command-line argumentn");
return 1;
}
}

使用isalpha():

7.4.1.2 isalpha函数简介

#include <ctype.h>
int isalpha(int c);

isalpha函数测试isupper或的任何字符Islower为真,或者是特定于语言环境的集合之一的任何字符对于没有iscntrol, isdigit, ispunct,或isspace为真。200)在"Locale, isalpha只返回trueisupper或islower为真值的字符

在你的代码中:

for (int i = 0; i < l; i++)
{
// see notes below regarding the cast
int charValue = ( unsigned char ) argv[1][i];
if ( isalpha( charValue ) )
{
printf("%cn", charValue); //to show me that it made it into the if statement
}
else
return 1;
}

请注意,传递的值必须可以表示为unsigned char:

标题声明几个用于分类和映射字符的函数。在所有情况下,实参都是int型,其值可以表示为无符号字符,或者等于宏EOF的值。如果参数有任何其他值,则行为未定义。

基本操作始终是遍历输入字符串中的字符并检查它们是否符合您的要求:大写字母还是小写字母。这里有一些函数使您编写代码更方便。

为了避免自己编码ASCII数字范围,您可以使用C标准函数isalpha()来检查单个字符是否为字母。

您还可以使用strcspn函数来查找字符串开头匹配字符的数量。您的匹配集可以是包含所有ASCII字母的字符串。如果返回的长度是整个字符串的长度,则其中没有其他字符。如果返回的长度小于字符串的长度,则存在一个非字母字符…对于计算机来说,这可能效率较低,因为strcspn不只是检查字符是否在一个范围内,而是检查字符是否出现在匹配的字符串中。

这个问题是关于测试非字母字符的。
已经有两个关于isalpha()的高质量答案。

meta-问题是"我怎样才能写更少的代码?"

下面(以isalpha()为例)提供了一个教学示例,其功能与上面的OP代码相同。通过将代码压缩到更少的行,读者可以在不滚动的情况下扫描其操作。未使用的变量,如inputs,可以快速找到并删除。

#include <stdio.h>
#include <string.h>
#include <cs50.h> // Missing from OP code
// defining the function ahead of its use. Definition is its own prototype.
int unique26( string arg ) {
int i = 0;
// test all alpha and is exactly 26 chars long
while( isalpha( (unsigned char) arg[i] ) i++;
if( i != 26 || arg[i] )
return 0; // bad
// test no duplications in the sample
for( i = 0; arg[i]; i++ )
for( int j = i + 1; arg[j]; j++ )
if( arg[j] == arg[i] )
return 0; // bad
return 1; // good
}
int main( int argc, string argv[] )
{
if( argc != 2 || !unique26( argv[1] ) )
{
printf( "Usage: %s <key (26 unique alphabetic chars> n", argv[0] );
return 1;
}
// more code here
return 0;
}

我很乐意回答这个示例代码中的任何问题。

编辑:
为了编写更少的代码,函数unique26()可以使用strchr(),这是一个经过测试和验证的函数,来自所谓的"C字符串库"。

int unique26( string arg ) {
int i = 0;
while( isalpha( (unsigned char) arg[i] ) i++;
if( i != 26 || arg[i] )
return 0; // bad
// test no duplications in the sample
for( i = 1; arg[i] && strchr( &arg[i], arg[i-1] ) == NULL; i++ ) {}
return arg[i] == ';
}

了解库函数是件好事,即使你可能不需要…直到你知道。

最新更新