原题
题目描述:计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000(注:字符串末尾不以空格结尾)
输入描述:输入一行,代表要计算的字符串,非空,长度小于5000;
输出描述:输出一个整数,表示输入字符串最后一个单词的长度。
示例1:
输入:hello nowcoder

输出:8

示例2:

输入:hello
输出:5


1. scanf的用法

如果遇到错误或遇到end of file,返回值为EOF
  • 只输入1个字符串:
scanf("%s", string);
这样只能输入一个字符串,任意空格,回车,TAB结尾,都是退出这句话,另算一个字符串的。

  • 只输入2个字符串:
scanf("%s", string1); 
scanf("%s", string2); 

  • scanf 投机取巧的方法: 输入多个字符串,取最后一个:
while( scanf("%s", string) != EOF )
  直接用strlen 计算长度即可,不用再找\0了。
#include "stdio.h"
#include "string.h"

int main()
{
    char buffer[5000];
    int i = 0;
    while(scanf("%s", buffer)!=EOF);

//     for(i=0; i< 5000; i++)
//     {
//         if(buffer[i] == '\0')
//             break;
//     }
    i = strlen(buffer);
    
    printf("%d", i);

    return 0;
}

2、使用scanf 方式输入字符串,并将其放入字符数组中;
     特别注意scanf输入时的 "%[^\n]" 操作,[^字符A] : 表明只有在遇到字符A时,输入才会截止
     同样scanf 还有"%[a-z]"  "%[0-9]" 操作,[字符/字符范围]:表明只有在字符或字符范围内,输入才有效
#include <string.h>
#include <stdio.h>

int main () {
    char word[5000] = {0};
    int length = 0;
    scanf("%[^\n]", word);
    for (int i = strlen(word)-1; i >= 0; i--) {
        if (word[i] == ' ') {
            break;
        }
        length++;
    }
    printf("%d\n", length);
    return 0;
}

其他gets,fgets,getchar,fgetc

gets,fgets

好处就在于他们对空格,制表符不敏感(这一点强于scanf)。
gets和fgets都能够读取一行,一行结束的标志是“回车”

gets用法

gets(buffer); 
length = strlen(buffer);
#include "stdio.h"
#include "string.h"

//gets 实现
int main()
{
    char buffer[5000];
    int i = 0;

    gets(buffer);
    int length = strlen(buffer);

    for(i=length-1;i>0;i--)
    {
        if(buffer[i] == ' ')
            break;
    }
    if(i==0)
        i = length;    //如果只有1个字符串,前面没有空格。
    else
        i = length - (i+1); //总长度,减掉空格前面的长度,就是最后个字符串的长度
    
    printf("%d", i);

    return 0;
}

fgets用法

r如果字符串长度为5  =  ‘hello’
fgets中的第二个参数需要填6,而不是5,因为这个函数会自动为字符串预留一个'\0',如果参数为5,读取返回值就为hell\0。

fgets(buffer, sizeof(buffer), stdin);
int length = strlen(buffer); //长度包含一个'/n'

strlen是计算到'\0'的长度,所以会多计算一个'\n'
#include "stdio.h"
#include "string.h"

//fgets 实现
int main()
{
    char buffer[5000];
    int i = 0;

    fgets(buffer, sizeof(buffer), stdin);
    int length = strlen(buffer);
    length = length - 1; //去掉‘\n’的这个字符

    for(i=length-1;i>0;i--)
    {
        if(buffer[i] == ' ')
            break;
    }
    if(i==0)
        i = length;    //如果只有1个字符串,前面没有空格。
    else
        i = length - (i+1); //总长度,减掉空格前面的长度,就是最后个字符串的长度
    
    printf("%d", i);

    return 0;
}

优秀代码:

/*libc库函数*/
int main(void)
{
    char str[100];
    while(scanf("%s",str)!=EOF);
    printf("%d",strlen(str));
}

/*快慢指针*/
#include <stdio.h>
int main(){
    int fast = 0;
    int slow = 0;
    char c;
    while(scanf("%c", &c) != EOF){
        if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == ' '))
            fast++;
        if (c == ' '){
            slow = fast;
        }
    }
    printf("%d\n", fast-slow);
    return 0;
}

解题思路
利用int型数组记录该字符串中每一个单词的长度,最后直接输出该数组中最后一个元素即可;
注意点
1、字符串长度小于5000,则字符数组的长度以及记录每个单词长度的int型数组的长度都需要大于5000;
2、使用gets函数输入一行字符串。scanf函数识别到' '(空格)则停止识别,而gets函数识别到'\n'(换行)则停止识别;
3、识别到空格则停止计数,且跳入下一个循环可以使用continue函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include<string.h>
const int max1=5000;
int main(){
    int i,k,count[max1];//使用count[max1]记录每个单词的长度
    char str[max1];//使用str[max1]记录字符串
    gets(str);//使用gets()函数读取字符串
    k=0;//k是单词长度数组的下标
    for(i=0;i<strlen(str);i++){
        if(str[i]==' '){
            k++;//识别到空格时,需要记录下一个单词的长度
            continue;
        }
        count[k]++;
    }
    printf("%d",count[k]);
    return 0;
}


strrchr() 查找最后一次出现某个字符(e.g.空格符)的地方的位置



gets获取所有字符串,用strrchr正序查找到最后一个字符串的起始位置

#include "stdio.h"
#include "string.h"

//gets 实现,用strrchr正序查找
int main()
{
    char buffer[5000];
    int i = 0;
    int result = 0;

    gets(buffer);
    char *p = strrchr(buffer, ' ');
    if(p==NULL)
        result = strlen(buffer);
    else
        result = strlen(p+1); //空格的下一个位置起始地址
    printf("%d", result);

    return 0;
}