尝试计数C中大写字母的数量时获取随机增量
我试图从输入中找到大写和小写字符的编号 这是我的密码:尝试计数C中大写字母的数量时获取随机增量,c,printf,C,Printf,我试图从输入中找到大写和小写字符的编号 这是我的密码: #包括 #包括 int main() { char cAFirst[25]; int k=0,uc=0,lc=0; fgets(cAFirst,25岁,标准日); //printf(“输出:%d\n”,k); 对于(大小i=0;i=97)和&(k考虑OP发布代码中的这段代码: char cAFirst[25]; // <- Uninitialized, the contents are indeterminated
#包括
#包括
int main()
{
char cAFirst[25];
int k=0,uc=0,lc=0;
fgets(cAFirst,25岁,标准日);
//printf(“输出:%d\n”,k);
对于(大小i=0;i<25;i++){
k=(int)cAFirst[i];
如果((k=65)){
uc++;
}
如果((k>=97)和&(k考虑OP发布代码中的这段代码:
char cAFirst[25]; // <- Uninitialized, the contents are indeterminated
// ...
fgets(cAFirst,25,stdin); // <- We don't know if it succeeded or not
// ...
for (size_t i = 0; i < 25; i++) {
// ... ^^^^^^
}
现在,即使在前一个循环中测试了数组中的所有字符,也不会有虚假值,统计数据也会保持一致。不过,这不是一个真正的解决方案,虽然通常建议在使用变量之前初始化所有变量,但在这种情况下,没有必要这样做
如所述,应检查函数(如fgets
)的返回值,以验证操作是否成功以及变量是否处于有效状态
if ( fgets(buf, BUF_SIZE, stdin) == NULL ) {
if (feof(stdin)) {
fprintf(stderr, "Abnormal end of input.\n");
// The contents of the array are not altered
}
if (ferror(stdin)) {
fprintf(stderr, "A stream error occurred.\n");
// The contents of the array are indeterminated, maybe not even null-terminated
}
exit(EXIT_FAILURE);
}
关键的一点是要确保在这次调用之后,数组以null结尾。即使是像下面这样的检查也足够了:
if ( fgets(buf, BUF_SIZE, stdin) == NULL ) {
fprintf(stderr, "An error occurred while reading from stdin.\n");
buf[0] = '\0';
// Continues the program despite the error, but with a valid (empty) string
}
值得记住的是,除了读取的字符外,任何其他字符都会保留在输入流中
现在我们有了一个有效的(以null结尾的)数组,我们可以通过它进行循环:
int uc = 0, lc = 0;
for (size_t i = 0; buf[i] != '\0'; i++) {
// which can also be written as 'for (size_t i = 0; buf[i]; i++) {'
// It's also more readable without magic numbers:
if ( 'A' <= buf[i] && buf[i] <= 'Z' ) {
uc++;
}
else if ( 'a' <= buf[i] && buf[i] <= 'z' ) {
lc++;
}
}
printf("Uppercase Letters = %i\nLowercase Letters = %i\n", uc, lc);
return EXIT_SUCCESS;
}
而不是总是迭代25次,迭代直到检测到输入结束
// for (size_t i = 0; i < 25; i++) {
for (size_t i = 0; cAFirst[i]; i++) { // detect null character.
//用于(大小i=0;i<25;i++){
对于(size_t i=0;cAFirst[i];i++){//检测空字符。
您应该首先使用一种方法,只对字符串进行一次迭代,可能是一次循环,并尝试读取不仅需要的内容,还可以读取不应该计数的内容。如果存在\t
或\n
您也需要它们计数吗
这里有一种方法可以帮助您理解:
#include <stdio.h>
int main( void )
{
char string[] = "AbcDEfgHiJKlmnOPqrstUVWxyZ\n§$%$§";
int uc, lc, i, others;
uc = lc = i = others = 0;
while ( string[i] )
{
if ( string[i] >= 'A' && string[i] <= 'Z' )
{
uc++;
}else if ( string[i] >= 'a' && string[i] <= 'z' ){
lc++;
}else{
others++;
}
i++;
}
if ( i == ( lc + uc + others ) )
{
printf( "OK\n\n" );
printf("Uppercase Letters = %i \nLowercase Letters = %i \nOthers = %d \n", uc, lc, others );
printf("Total = %d\n", i );
}else
{
printf("Something went Wrong.\n\n");
}
}
尝试for(size_t i=0;i<25;i++)
-->for(size_t i=0;cAFirst[i];i++)
还可以更改if((k='A'))
等条件以提高可读性。if((k=65))
if(isupper(k))
和if((k>=97)和if(islower k))
。您可以在单引号中使用字符本身,而不是使用字符的数值。因此if((k=65)){
也可以写入if((k='a')){
这样做可以让代码更容易理解您正在做的事情。另外,您只需要处理实际输入的字符数,而不需要处理整个数组。因此,如果输入的字符数只有2个,那么您只需要执行两次循环。因此,您不需要执行全部25个字符,而需要执行到最后如果只输入了“xyz\n”
,您还想让代码重复25次吗?char-cAFirst[25]={};
=>char-cAFirst[25]={0};
空初始化列表无效C(可能有效的是我不知道的某种语言)。这是一个技术细节,但新行字符,'\n'
不是文本字符,因此无论如何都不会计算。我很好奇,如果用户输入的字符超过25个,会发生什么情况。@RichardChambers,如果输入的字符超过24个('\n'
是一个字符),它们将保留在stdin
中,以备以后使用。@RichardChambers“在第一次读取时也没有新行。”不清楚。为什么会出现这种情况?strcspn(cAFirst,“\n”)
的功能不清楚吗?
// for (size_t i = 0; i < 25; i++) {
for (size_t i = 0; cAFirst[i]; i++) { // detect null character.
#include <stdio.h>
int main( void )
{
char string[] = "AbcDEfgHiJKlmnOPqrstUVWxyZ\n§$%$§";
int uc, lc, i, others;
uc = lc = i = others = 0;
while ( string[i] )
{
if ( string[i] >= 'A' && string[i] <= 'Z' )
{
uc++;
}else if ( string[i] >= 'a' && string[i] <= 'z' ){
lc++;
}else{
others++;
}
i++;
}
if ( i == ( lc + uc + others ) )
{
printf( "OK\n\n" );
printf("Uppercase Letters = %i \nLowercase Letters = %i \nOthers = %d \n", uc, lc, others );
printf("Total = %d\n", i );
}else
{
printf("Something went Wrong.\n\n");
}
}
if ( isupper( string[i] ) )
{
uc++;
}else if ( islower( string[i] ) )
{
lc++;
}else{
others++;
}