每日一题|如何判断回文数?

老规矩,先放代码。

//回文数 
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int main(void)
{
    char* input = NULL;
    int size  = 100;
    input = (char*)malloc(size*sizeof(char));//动态分配内存,最后别忘了free;
    printf("Input string:");
    fgets(input,size,stdin);
    input[strcspn(input,"\n")] = '\0';//这里注意,fgets会读入换行符,这里需要将换行符去除。
    int len = strlen(input);
    int isplalindrome = 1;//使用0和1判断
    for(int i = 0;i < len/2;i ++)
    {
        if (*(input + i) != *(input + len - 1 -i))//将指针当作数组用。input + i == input[0 + i]
        {
            isplalindrome = 0;//证明不是回文数
            break;
        }
    }
    if (isplalindrome == 1)
    {
        printf("Yes");
    }
    else printf("No");
    free(input);
    return 0;
}

  • 关于换行符的问题

在敲代码的过程中,笔者还注意到了一个有意思的小细节。

fgets(input,size,stdin);

由于习惯,笔者采用了更为安全的输入方式fgets。相比于已经废弃的gets,这种输入方式可以有效地防止溢出,当我们的输入长度超过size时,fgets会自动截取size内的字符而防止报错(类似于scanf函数中的%100s)。

然而在运行时,笔者却发现使用gets函数能正确地判断是否为回文数,但是fgets函数却总是输出“NO”。明明fgets函数更安全,为什么使用它就会报错呢?

我们通过实践,先了解strlen函数、gets函数和fgets函数的性质。

#include "stdio.h"
#include "string.h"
int main(void)
{
    char str1[10] = "student";
    char str2[10],str3[10];
    gets(str2);
    fgets(str3,10,stdin);
    printf("length of str1 = %d\n",strlen(str1));
    printf("length of str2 = %d\n",strlen(str2));
    printf("length of str3 = %d\n",strlen(str3));
    return 0;
}

在段代码中,我们使用初始化、gets函数输入、fgets函数输入三种方式,分别定义了字符串"student",随后用strlen函数计算并输出他们的长度。

那么结果是什么呢?

student
student
length of str1 = 7
length of str2 = 7
length of str3 = 8

进程已结束,退出代码为 0

我们看到,同样是输入了相同的字符串,str3的长度比str2多了1.这是为什么呢?

我们再对代码做一点小小的修改:

#include "stdio.h"
#include "string.h"
int main(void)
{
    char str1[10] = "student";
    char str2[10],str3[10];
    gets(str2);
    fgets(str3,10,stdin);

    str3[strcspn(str3,"\n")] = '\0';//使用strcspn函数清除可能存在的换行符
    
    printf("length of str1 = %d\n",strlen(str1));
    printf("length of str2 = %d\n",strlen(str2));
    printf("length of str3 = %d\n",strlen(str3));
    return 0;
}
student
student
length of str1 = 7
length of str2 = 7
length of str3 = 7

进程已结束,退出代码为 0

此时长度一样了!

由此我们可以得出三个结论:

  1. gets函数输入不包括换行符;
  2. fgets函数输入包括换行符;
  3. strlen函数计算长度时,会包含换行符的长度,但不包含终止符'\0'的长度.

因此在初始代码中,笔者使用fgets后,并没有通过strcspn()搜索存在的换行符并将其替换成终止符'\0',导致字符串长度计算错误(总是多1)(比如student的长度本来是7,因为多了换行符而计算成8),除非在前后都输入换行符,否则回文数的计算会一直出现错误。

注意到此点后,笔者又上手实践了一下,证明scanf函数也不会读入换行符。但是scanf函数在读取数据时会忽略空白字符,包括空格、制表符和换行符。这意味着,如果我们在输入数据之间或之后按下了回车键,scanf函数会自动忽略这些换行符,并继续等待下一个非空白字符的输入。

由此,我们在使用fgets函数时,不要忘记清除可能存在的换行符。

over.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值