写个字符串trim,发现strlen有问题

-- TOC --

本来只想想写个字符串的trim接口,但在测试时候,发现strlen接口有问题

请看代码和执行情况:

$ cat test_trim.c
#include <stdio.h>
#include <string.h>
#include <ctype.h>


char *trim(char *p) {
    if (strlen(p) == 0)
        return p;

    while (isspace(*p))
        p++;

    char *t = p + strlen(p) - 1;
    while (isspace(*t))
        *t-- = '\0';

    return p;
}


int main(void) {
    char t0[] = "";
    // t0 is the start address pointer, be careful if you need free.
    char *t0a = trim(t0);
    printf("trim(%s,%zu)=%s,%zu\n", t0, strlen(t0), t0a, strlen(t0a));

    char t1[] = "    ";
    char *t1a = trim(t1);
    printf("trim(%s,%zu)=%s,%zu\n", t1, strlen(t1), t1a, strlen(t1a));

    char t2[] = "abcde";
    char *t2a = trim(t2);
    printf("trim(%s,%zu)=%s,%zu\n", t2, strlen(t2), t2a, strlen(t2a));

    char t3[] = "      abcde   ";
    char *t3a = trim(t3);
    printf("trim(%s,%zu)=%s,%zu\n", t3, strlen(t3), t3a, strlen(t3a));

    char t4[] = " ab cd e        ";
    char *t4a = trim(t4);
    printf("trim(%s,%zu)=%s,%zu\n", t4, strlen(t4), t4a, strlen(t4a));

    char t5[] = {' ', '\t', 'a', '\t', 'b', ' ', '\0'};
    char *t5a = trim(t5);
    printf("trim(%s,%zu)=%s,%zu\n", t5, strlen(t5), t5a, strlen(t5a));

    char t6[] = {'\0'};
    char *t6a = trim(t6);
    printf("trim(%s,%zu)=%s,%zu\n", t6, strlen(t6), t6a, strlen(t6a));

    return 0;
}
$ gcc -Wall -Wextra test_trim.c -o trim
$ ./trim
trim(,0)=,0
trim(,0)=,0
trim(abcde,5)=abcde,5
trim(      abcde,11)=abcde,5  // 11, not include trailing space
trim( ab cd e,8)=ab cd e,7    // 4
trim(   a       b,5)=a  b,3   // 5
trim(,0)=,0

trim接口符合预期,而strlen有问题的点:

strlen返回的结果不符合预期,我觉得它应该只把末尾的\0符号排除在外,但是实际上,它基本上将末尾的所有space符号都排除了。(这是对的吗?这样的话,trim接口的后面一半就可以不需要了,额...)

打印size_t,使用%zu

写trim的初衷,是用来处理argv这个main参数,它的各个参数中,可能在前后都含有空格。main接口的argv指针数组中的每个指针,是可以修改的,type并没有用const这个qualifier。(参考:详解C语言的const申明

使用方法如下:

int main(int argc, char **argv) {
    // ...
    for (int i=0; i<argc; ++i)
        argv[i] = trim(argv[i]);
    // ...
}

将每个argv[i]指向第1个非space char,同时字符串末尾的space全部修改为\0,即让它前结束。

本文链接:https://cs.pynote.net/sf/c/202205031/

-- EOF --

-- MORE --