c语言求单词长度(含指针,strtok函数等方法)

scanf连续读取字符串

注意逗号处理,除第一个单词以外,每个单词前都有逗号

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

int main() {
    char s[100];
    int flag = 1; // 使用 1 表示第一个单词
    while (scanf("%s", s) == 1) {
        if (flag) {
            flag = 0;
            printf("%lu", strlen(s));
        } else {
            printf(",%lu", strlen(s));
        }
    }
    return 0;
}

该题还可以读入一整行后做处理

读取一整行

可选用函数有fgets,gets,和scanf("%[^\n]",s)三种

scanf("%[^\n]", str) 和 gets(str) 都可以用来读取一行字符串,但它们之间有以下区别:

安全性:scanf 函数在处理字符串时存在潜在的缓冲区溢出问题,因为它没有指定最大输入长度。如果输入的字符串超过了目标数组的大小,就会导致缓冲区溢出。而 gets 函数更不安全,因为它没有提供字符数目的限制,可能导致更严重的内存溢出问题。而fgets最安全但会读取末尾的换行符,造成最后一个数字在编译器上测试时可能会大1,而在洛谷ide交题无碍。

指针

#include <stdio.h>

int main() {
    char str[1000];
    fgets(str, 1000, stdin); // 读取输入的字符串

    char *ptr = str;
    while (*ptr != '\0') {
        if (*ptr != ' ') { // 如果当前字符不是空格
            int length = 0;
            while (*ptr != ' ' && *ptr != '\0') { // 统计单词长度
                length++;
                ptr++;
            }
            printf("%d", length);
            if (*ptr != '\0') {
                printf(","); // 输出逗号
            }
        } else {
            ptr++;
        }
    }

    return 0;
}

对于第二个while循环,条件要注意

 while (*ptr != ' ' && *ptr != '\0')

不仅考虑空格还要考虑指针不能越界

strtok(逗号处理更自然)

#include <stdio.h>
#include <string.h>
int main()
{
    char s[1000];
    char str[]=" ";
    scanf("%[^\n]",s);

    char*token=strtok(s,str);
    while(token!=NULL)
    {
        printf("%lu",strlen(token));
        token=strtok(NULL,str);
        if(token!=NULL)
        {
            printf(",");
        }
    }
}

strtok函数返回被分解的第一个子字符串,若无可检索的字符串,则返回空指针

注意:在这个函数里strtok()在分解字符串的时候,第一个参数是在不断变化的,这个函数是在改变原字符串,所以第一个字符串不能是常量字符串

strtok简化版函数源码
char *strtok(char *str, const char *delim) {
    static char *next_start = NULL;  // 保存到静态存储区,函数返回后不会被销毁

    // 如果传入的 str 为 NULL,并且 next_start 也为 NULL,则返回 NULL
    if (str == NULL && (str = next_start) == NULL) {
        return NULL;
    }

    char       *s = str;  // 初始化 s 指针指向传入的字符串
    const char *t = NULL;  // t 是分隔符字符串 delim 的指针

    // 遍历字符串直到结束
    while (*s) {
        t = delim;  // 将 t 指针指向分隔符字符串

        // 遍历分隔符字符串 delim
        while (*t) {
            if (*t == *s) {  // 如果发现当前字符是分隔符
                next_start = s + 1;  // 更新 next_start 指向下一个待处理字符的位置

                if (s == str) {  // 如果第一个字符就是分隔符
                    str = next_start;  // 更新 str 指针指向下一个待处理字符的位置
                    break;  // 跳出内层循环
                } else {
                    *s = '\0';  // 将当前字符设为字符串结尾
                    return str;  // 返回上一个子字符串的起始地址
                }
            } else {
                t++;  // 继续比较下一个分隔符字符
            }
        }

        s++;  // 继续处理下一个字符
    }

    return NULL;  // 处理完整个字符串后返回 NULL
}

next_start 是一个静态指针,在函数内部用来保存下一个待处理字符的位置。它的作用是在多次调用 strtok 函数时,保持上一次处理结束后下一个待处理字符的位置,从而实现对同一个字符串的连续分割。

具体来说,next_start 的作用是记录上一次 strtok 函数处理的位置,以便下一次调用 strtok 时能够从上一次结束的地方继续处理字符串。这样可以实现在一个循环中多次调用 strtok 来逐个获取被分割的子字符串。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值