菜单开关

周梦康 发表于 2017-09-17 2127 次浏览 标签 : C语言快速入门

strtok 演示

期望的结果是s字符串被截断为12345

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

int main(int argc, char const *argv[])
{
    char *s = "123456789";
    char *tmp = NULL;

    tmp = strtok(s, "6");

    printf("%s\n", s);
    return 0;
}

实际运行的结果为

Bus error: 10

修改下

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

int main(int argc, char const *argv[])
{
    // char *s = "123456789";
    char s[10] = "123456789";

    char *tmp = NULL;

    tmp = strtok(s, "6");

    printf("%s\n", s);
    return 0;
}

结果正常了

zhoumengkang@bogon:~/Downloads$ gcc test2.c -o test2
zhoumengkang@bogon:~/Downloads$ ./test2
12345

char *s是存在只读区(常量区),不能被改写;
char s[10]是存在栈上,是可以随意改写的。

用字符串初始化指针时,此时的字符串是放在静态存储区的,而用字符串来初始化数组,此时的字符串却是局部变量。

扩展演示

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

int main(int argc, char const *argv[])
{
    char *a = "123456789";
    char b[10] = "123456789";


    printf("a\t%p\n", a);//只读区
    printf("a的指针的地址\t%p\n", &a);//栈
    printf("b\t%p\n", b);//栈
    printf("main\t%p\n", main);//代码区
    return 0;
}

运行结果

a    0x100a4cf74
a的指针的地址    0x7fff5f1b3ac0
b    0x7fff5f1b3ade
main    0x100a4ce80

PHP 源码实战

php 里有一个 urldecode 的字符串的函数

size_t php_url_decode(char *str, size_t len) {
    char *dest = str;
    char *data = str;

    while (len--) {
        if (*data == '+') {
            *dest = ' ';
        } else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) {
            *dest = (char) php_htoi(data + 1);
            data += 2;
            len -= 2;
        } else {
            *dest = *data;
        }
        data++;
        dest++;
    }
    *dest = '\0';
    return dest - str;
}

但是这里的 str 我们能传入一个字符串么,比如这样

char *str = "ab+cd";
php_url_decode(str, strlen(str));

结果是不行的,因为字符串是只读的,常量区,不可修改的。所以这里只能用 char 数组,因为数组的定义内存申请是在栈上的,就不会有问题了。

char a[6] = {"ab+cd"};
php_url_decode(a, strlen(a));
printf("%s\n", a);

评论列表