一文搞懂JSON

news2024/9/23 15:28:35

目录

什么是JSON?

JSON的基本数据类型

JSON的特点和优势(了解)

JSON格式规范(重点)

JSON的基本操作

关键接口的梳理

序列化

反序列化

答案和解析

序列化答案

反序列化答案

第一种思路

第二种思路


什么是JSON?

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于将数据结构化地传输和存储。它由键值对组成,采用类似于JavaScript对象的格式来表示数据。JSON易于阅读和编写,并且易于解析和生成,成为广泛应用于Web应用程序和数据交换的标准格式之一。

JSON的基本数据类型

类型

解释

案例

字符

(String)

由双引号包围的Unicode字符序列

"Hello, World!"

数字(Number)

包括整数和浮点数

42,3.14

布尔值(Boolean)

表示真或假,C相关的实现库可能会用0和1表示

值为true或false

空值

(Null)

表示空值

值为null

对象

(Object)

由一组无序的键值对组成,键是字符串,值可以是任意的JSON数据类型。键值对之间使用逗号分隔,整个对象使用花括号{}包围

{"name": "John",

"age": 30,

"city": "New York"}

数组

(Array)

由一组有序的值组成,值可以是任意的JSON数据类型。值之间使用逗号分隔,整个数组使用方括号[]包围

[1, 2, 3, 4, 5]

JSON的特点和优势(了解)

  1. 简洁和易读:JSON使用简洁的文本格式表示数据,易于阅读和编写。
  2. 平台无关性:JSON是一种独立于编程语言和平台的数据格式,可被多种编程语言解析和生成。
  3. 易于解析和生成:JSON的解析和生成相对简单,各种编程语言都提供了相应的JSON解析器和生成器。
  4. 支持复杂数据结构:JSON支持嵌套、复杂的数据结构,可以表示对象、数组和各种组合类型的数据。
  5. 与Web应用程序兼容性良好:JSON广泛用于Web应用程序中,可以轻松地与JavaScript进行交互。

JSON格式规范(重点)

1. 数据使用键值对表示,键和值之间使用冒号(:)分隔。
	例如:{"name": "John", "age": 30}
2. 键使用双引号(")包围,值可以是字符串、数字、布尔值、对象、数组或null。 
	例如:{"name": "John", "age": 30, "isStudent": true, "address": null}
3. 键值对之间使用逗号(,)分隔,最后一个键值对后不应有逗号。 
	例如:{"name": "John", "age": 30}
4. 字符串值使用双引号(")包围,可以包含任意Unicode字符序列,特殊字符可以使用转义字符表示。 
	例如:"Hello, World!", "I "love" JSON"
5. 数字可以是整数或浮点数,不使用引号包围。 
	例如:42, 3.14
6. 布尔值只有两个取值:true和false,不使用引号包围。 
	例如:true, false
7. 数组使用方括号([])包围,值之间使用逗号分隔。 
	例如:[1, 2, 3, 4, 5]
8. 对象使用花括号({})包围,键值对之间使用逗号分隔。 
	例如:{"name": "John", "age": 30}
9. JSON是严格区分大小写的,键和字符串值都应该使用双引号包围。
10. JSON可以嵌套,允许在对象中包含对象或数组,或在数组中包含对象或其他数组。
11. JSON不支持注释,不允许在JSON数据中添加注释。

下面是一个简单的JSON

{
  "name": "southernbrid",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

分享个JSON格式校验网站

在线JSON校验格式化工具(Be JSON)

JSON的基本操作

JSON的基本操作通常涉及以下几个方面:

  1. 创建JSON对象: 可以使用编程语言提供的函数、类或库来创建JSON对象。通常,这些函数或方法接受键值对作为参数,用于指定JSON对象的属性和对应的值。
  2. 解析JSON字符串: 将JSON字符串解析为相应的数据结构,如对象、数组或基本数据类型。编程语言提供相应的解析函数或方法,可以将JSON字符串转换为可操作的数据对象。
  3. 生成JSON字符串: 将数据对象转换为JSON字符串的表示形式,以便于传输、存储或与其他系统进行交互。编程语言提供相应的函数或方法,可以将数据对象转换为符合JSON格式规范的字符串。
  4. 访问和修改JSON对象的属性: 通过键访问JSON对象的属性,并可以对其进行修改。可以使用编程语言提供的API来访问、读取和修改JSON对象的属性值。
  5. 遍历JSON数组: 遍历JSON数组中的元素,逐个访问和处理数组中的数据项。使用循环结构来遍历数组,根据索引或迭代器获取数组中的每个元素。
  6. 嵌套JSON操作: 处理嵌套的JSON结构,包括访问、修改和操作嵌套的对象或数组。可以使用递归、循环等方法来处理嵌套的JSON结构。
  7. 序列化和反序列化(重点): 将JSON对象序列化为字符串,或将JSON字符串反序列化为对象。序列化是将数据对象转换为JSON字符串,反序列化是将JSON字符串转换为数据对象。(本文主要介绍C语言的JSON库来进行序列化和反序列化)

下面是一个C库,用来完成本文教学

📎cJSON.chttps://www.yuque.com/attachments/yuque/0/2023/txt/35243076/1687951166715-b8398dec-d697-4507-b49e-1e2ea5595ce9.txt📎cJSON.hhttps://www.yuque.com/attachments/yuque/0/2023/txt/35243076/1687951166713-f66a28ef-8aaa-4fb0-8f7c-7fa49d94b608.txt

下面两篇文章也能帮助我们完成JSON序列化和JSON反序列化的操作

cJSON 使用详解_无痕眼泪的博客-CSDN博客由于c语言中,没有直接的字典,字符串数组等数据结构,所以要借助结构体定义,处理json。如果有对应的数据结构就方便一些, 如python中用json.loads(json)就把json字符串转变为内建的数据结构处理起来比较方便。一个重要概念:在cjson中,json对象可以是json,可以是字符串,可以是数字。。。cjson数据结构定义:#d..._cjsonhttps://blog.csdn.net/qq_32172673/article/details/88305781

https://www.cnblogs.com/liunianshiwei/p/6087596.htmlhttps://www.cnblogs.com/liunianshiwei/p/6087596.html

编译注意事项

编译cJSON库时候,gcc需要增加  -lm 选项,动态链接math库。

关键接口的梳理

/* 类型定义 */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

/* CJSON核心结构体 */
typedef struct cJSON {
struct cJSON *next,*prev;	/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

int type;					/* 节点的类型,取值是上面的6种 */

char *valuestring;			/* 如果类型是cJSON_String,那么值会被存到这里 */
int valueint;				/* 如果类型是cJSON_Number,且是整型,那么值会被存到这里 */
double valuedouble;			/* 如果类型是cJSON_Number,且是浮点型,那么值会被存到这里 */

char *string;				/* 键*/
} cJSON;

/****************************通用接口****************************/
//把传入的字符串转成cJSON的结构(反序列化)
cJSON *cJSON_Parse(const char *value);
//把cJSON结构转成字符串(序列化),调用后需要配合free接口释放malloc的内存
char  *cJSON_Print(cJSON *item);
//无格式化序列化,节省内存,调用后需要配合free接口释放malloc的内存
char  *cJSON_PrintUnformatted(cJSON *item);
//释放节点的内存,防止内存泄露
void   cJSON_Delete(cJSON *c);

/****************************反序列化相关接口****************************/
//获取数组的大小
int	  cJSON_GetArraySize(cJSON *array);
//从array数组中获取第item个子节点
cJSON *cJSON_GetArrayItem(cJSON *array,int item);
//获取object大节点名字叫string的子节点
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
//判断object大节点中是否有名字叫string的小节点
int cJSON_HasObjectItem(cJSON *object,const char *string);

/****************************序列化相关接口****************************/
//创建一个普通节点
cJSON *cJSON_CreateObject(void);
//创建一个数组节点
cJSON *cJSON_CreateArray(void);
//把item节点增加到array的数组节点中
void cJSON_AddItemToArray(cJSON *array, cJSON *item);
//把item节点增加到object中作为子节点,item节点的键名为string
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);

//创建各种类型的cJSON节点
cJSON *cJSON_CreateNull(void);
cJSON *cJSON_CreateTrue(void);
cJSON *cJSON_CreateFalse(void);
cJSON *cJSON_CreateBool(int b);
cJSON *cJSON_CreateNumber(double num);
cJSON *cJSON_CreateString(const char *string);
cJSON *cJSON_CreateArray(void);
cJSON *cJSON_CreateObject(void);

序列化

使用cJSON库序列化出下面的JSON内容

{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

反序列化

使用cJSON库对下面的JSON文件进行反序列化操作。ver和login的子节点直接打印即可,data的数据节点解析后形成链表存储(将下面内容存为文件,读取后解析即可)。

{
  "ver": "1.0",
  "login": {
    "user": "zhangsan",
    "pwd": 1234
  },
  "data": [{
    "key": 1,
    "type": 2,
    "val": "10"
  },
    {
      "key": 2,
      "type": 1,
      "val": "0"
    },
    {
      "key": 3,
      "type": 3,
      "val": "22.5"
    }
  ]
}

注意:上面的所有val值都是string类型,解析出来存到节点前,需要根据type的类型来进行转换,按照相应的类型存储到共用体中。

提示:对于数据解析后,形成新的节点存放链表,最好的方式是为每个节点分配单独的内存。例:

struct data {
int key;
int type;
union val_t val;
struct list_head list;
};

struct data *node = (struct data *)malloc(sizeof(struct data));
node->xxx = xxx;
插入链表即可

答案和解析

序列化答案

#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    // 序列化
    cJSON *root = cJSON_CreateObject(); // 创建根节点

    cJSON *age = cJSON_CreateNumber(14); // 创建一个数值类型的节点
    cJSON_AddItemToObject(root, "age", age); // 将age节点添加到root对象中,键名为"age"

    // 增加数组节点
    cJSON *arr = cJSON_CreateArray(); // 创建一个数组类型的节点
    cJSON_AddItemToArray(arr, cJSON_CreateString("JavaScript")); // 向数组中添加一个字符串节点
    cJSON_AddItemToArray(arr, cJSON_CreateString("Java")); // 向数组中添加一个字符串节点
    cJSON_AddItemToArray(arr, cJSON_CreateString("Python")); // 向数组中添加一个字符串节点

    cJSON_AddItemToObject(root, "skills", arr); // 将数组节点添加到root对象中,键名为"skills"

    // 输出内容
    char *p = cJSON_PrintUnformatted(root); // 将JSON对象转换为字符串表示形式
    printf("root = %s\n", p);
    free(p);
    cJSON_Delete(root); // 释放JSON对象占用的内存
    return 0;
}

反序列化答案

第一种思路

#include <stdio.h>
#include "cJSON.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "list.h"
#include <string.h>

#define MAX 1024

union val_t
{
    int i_val;
    float f_val;
    char *s_val[MAX];
};

struct data {
    int key;
    int type;
    union val_t val;
    struct list_head list;
};

int main(int argc, char const *argv[])
{
    // 构造链表
    struct list_head head;
    INIT_LIST_HEAD(&head);
    struct data mydate[10]; // 创建结构体数组

    // 读取文件内容到缓冲区
    int fd = open("data.json", O_RDONLY);
    if (fd < 0)
    {
        perror("open err");
        return -1;
    }
    char buf[MAX] = {0};
    size_t len = read(fd, buf, MAX);
    if (len < 0)
    {
        perror("open err");
        return -1;
    }

    // 反序列化动作
    cJSON *root = cJSON_Parse(buf); // 把传入的字符串转成cJSON的结构(反序列化)
    if (root == NULL)
    {
        printf("cJSON_Parse err.");
        return -1;
    }

    // 开始摘取数据
    cJSON *item;
    cJSON *keyitem;
    cJSON *typeitem;
    cJSON *valitem;

    item = cJSON_GetObjectItem(root, "ver"); // 获取root的ver子节点
    printf("%s : %s\n", item->string, item->valuestring);

    cJSON *login = cJSON_GetObjectItem(root, "login");
    cJSON *user = cJSON_GetObjectItem(login, "user");
    cJSON *pwd = cJSON_GetObjectItem(login, "pwd");
    printf("%s :\n", login->string);
    printf("%s : %s\n", user->string, user->valuestring);
    printf("%s : %d\n", pwd->string, pwd->valueint);

    // 解析数组节点
    cJSON *data;
    data = cJSON_GetObjectItem(root, "data");
    printf("%s :\n", data->string);
    int count = cJSON_GetArraySize(data); // 获取数组大小用来进行遍历

    for (size_t i = 0; i < count; i++)
    {
        cJSON *tmp = cJSON_GetArrayItem(data, i); // 获取数组节点中的第 i 个元素

        keyitem = cJSON_GetObjectItem(tmp, "key");
        typeitem = cJSON_GetObjectItem(tmp, "type");
        valitem = cJSON_GetObjectItem(tmp, "val");
        printf("key : %d\n", keyitem->valueint);
        printf("type : %d\n", typeitem->valueint);
        printf("val : %s\n", valitem->valuestring);

        mydate[i].key = keyitem->valueint;                 // 设置key值
        mydate[i].type = typeitem->valueint;               // 设置类型
        strcpy(mydate[i].val.s_val, valitem->valuestring); // 将值拷贝到val数组
        list_add(&mydate[i].list, &head);                  // 将结构体添加到链表中
    }

    // 遍历链表并输出结果
    struct list_head *pos;
    struct data *newtmp;

    list_for_each(pos, &head)
    {
        newtmp = list_entry(pos, struct data, list);
        printf("key = %d, type = %d, val = %s\n", newtmp->key, newtmp->type, newtmp->val.s_val);
    }

    list_del(pos);
    cJSON_Delete(root); // 释放JSON对象占用的内存
    return 0;
}

第二种思路

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "cJSON.h"
#include "list.h"

//定义共用体
typedef int BOOL;

union val_t
{ 
    BOOL b_val;  //bool类型存储空间
    int i_val;   //整形值存储空间
    float f_val;  //浮点值存储空间
};

//定义结构体
struct student
{
    int key;
    int type;
    union val_t val;
    struct list_head list;//指针域
};
int main(int argc, char const *argv[])
{
    struct list_head head;
    INIT_LIST_HEAD(&head);
    char * jsonStr = "{\"ver\":\"1.0\",\"login\":{\"user\":\"zhangsan\",\"pwd\":1234},\"data\":[{\"key\":1,\"type\":2,\"val\":\"10\"},{\"key\":2,\"type\":1,\"val\":\"0\"},{\"key\":3,\"type\":3,\"val\":\"22.5\"}]}";
    cJSON * root = NULL;
    cJSON * item = NULL;//cjson对象
    //把传入的字符串转成cJSON的结构(反序列化)
    root = cJSON_Parse(jsonStr);//取出root对象(根节点)
    if (!root) 
    {
        printf("Error before: [%s]\n",cJSON_GetErrorPtr());
        return -1;
    }
    else
    {
        printf("转换成功!\n");
        //获取版本号--ver
        item = cJSON_GetObjectItem(root, "ver");
        printf("版本号%s:%s\n",item->string,item->valuestring);
        //获取帐号密码
        item = cJSON_GetObjectItem(root, "login");
        cJSON * myuser = cJSON_GetObjectItem(item, "user");
        printf("帐号%s:%s   ---   ",myuser->string,myuser->valuestring);
        cJSON * mypwd = cJSON_GetObjectItem(item, "pwd");
        printf("密码%s:%d\n",mypwd->string,mypwd->valueint);
        cJSON * myData = cJSON_GetObjectItem(root, "data");//root节点下的data节点
        item = myData->child;//item是数组或对象的子节点,即data节点下的每一个小的花括号节点,或者可以用cJSON *cJSON_GetArrayItem(cJSON *array,int item)获取数组中的子节点(花括号节点)
        printf("data数据列表:\n");
        while(item != NULL)
        {
            //取出data里的每一个花括号里的每一个小元素的值:即(key,type,val)的值
            cJSON * mykey = cJSON_GetObjectItem(item, "key");
            printf("键:%d ",mykey->valueint);
            cJSON * mytype = cJSON_GetObjectItem(item, "type");
            printf("类型:%d ",mytype->valueint);
            cJSON * myval = cJSON_GetObjectItem(item, "val");//注意val的数据类型
            printf("值:%s\n",myval->valuestring);
            if(mykey != NULL && mytype != NULL && myval != NULL)
            {
                // printf("取值成功!以链表方式存储\n");
                //将解析的数据放入链表中
                struct student * stu = (struct student *)malloc(sizeof(struct student));//记得释放内存
                stu->key = mykey->valueint;
                stu->type = mytype->valueint;
                if(mytype->valueint == 1)
                {
                    int valnum = atoi(myval->valuestring);
                    stu->val.i_val = valnum;
                }
                else if(mytype->valueint == 2)
                {
                    int valnum = atoi(myval->valuestring);
                    stu->val.i_val = valnum;
                }
                else if(mytype->valueint == 3)
                {
                    int valnum = atof(myval->valuestring);
                    stu->val.f_val = valnum;
                }
                // stu->val.i_val = myval->valuestring;
                //头插法插入
                list_add(&stu->list,&head);
            }
            item = item->next;
        }
    //遍历打印
    struct list_head *pos;//是指向一个结构体的一个指针域的指针
    struct student *tmp;//是指向整个结构体的指针
    // printf("init list\n");
    printf("链表数据:\n");
    list_for_each(pos, &head)
    {
        // sleep(3);
        tmp = list_entry(pos, struct student, list);//可以从指针域偏移到整个结构体,拿到整个结构体的首地址,因此能够拿到属于该指针域的数据域
        if(tmp->type == 1)
        {
            printf("key=%d, type=%d, val=%d\n", tmp->key, tmp->type, tmp->val.i_val);
        }
        else if(tmp->type == 2)
        {
            printf("key=%d, type=%d, val=%d\n", tmp->key, tmp->type, tmp->val.b_val);
        }
        else if(tmp->type == 3)
        {
            printf("key=%d, type=%d, val=%.2f\n", tmp->key, tmp->type, tmp->val.f_val);
        }
    }
    printf("\n");
    }
    cJSON_Delete(root);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/697127.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux4.vim

1.vim 三种模式 : 命令模式的常见命令 : 底行模式 : 2.sudo 信任名单的位置 : /etc/sudoers 添加信任名单 :以root身份&#xff0c;使用vim打开信任名单&#xff0c;显示行号&#xff0c;大概在104行。

数字化车间数字孪生可视化提高资产利用率

车间管理中往往存在以下几方面问题&#xff1a; 1、产品加工过程复杂、工序繁多;产品在生产制造过程中由于设备和工艺等原因产生不确定因素会影响最终产品质量; 2、生产计划制定困难、生产任务无法及时完成导致生产计划执行困难; 3、业务需求不明确或变化频繁造成车间管理工作无…

360手机驱动提取 360手机驱动安装 360手机高通驱动

360手机驱动提取 360手机驱动安装 360手机高通驱动 参考&#xff1a;360手机-360刷机360刷机包twrp、root 360刷机包360手机刷机&#xff1a;360rom.github.io 【360手机驱动提取】 注&#xff1a;期间手机提示授权&#xff0c;请勾选同意 打开手机&#xff1a;开发者模式&a…

楚天云淡风更长--2023华为主题创意工作坊武汉站侧记

create:2023-06-28 楚 三镇锁大江 名城历千秋。 华中重地&#xff0c;中心城市优势引领区域经济发展。 无论是古老的楚越文化、离骚诗赋&#xff0c; 还是后世追起的黄鹤高楼、千载悠悠&#xff0c; 或是明清以降的开风气之先河&#xff0c; 又以工业重镇立于现代城市之林&am…

【Servlet学习三】实现一个简单的数据库版本的留言墙!

目录 一、前期环境搭建 二、具体后端代码实现 &#x1f308;1、创建数据库 &#x1f308;2、创建message类&#xff1a;定义属性和相应的get和set方法 &#x1f308;3、创建JDBC工具类&#xff1a;DBUtil文件&#xff0c;定义一些数据库的基本操作 &#x1f308;4、创建m…

浅谈注册表读取所需要付出的性能代价

Windows 系统的特色功能&#xff0c;注册表&#xff0c;是一个十分方便有用的工具。它可以用来以一种统一和多线程安全的方式来永久性的保存数据。如果你将数据保存在 HKEY_CURRENT_USER 键下&#xff0c;则数据可以随着用户一起漫游&#xff0c;并且可以保护单个键值 (即使是在…

1 Prometheus-监控简介

目录 1 什么是监控 1.1 技术作为客户 1.2 业务作为客户 2. 监控基础知识 2.1 事后监控 2.2 机械式/模板式/无脑式监控 2.3 不够准确的监控 2.4 静态监控 2.5 不频繁的监控 2.6 缺少自动化或操作繁琐/不便 2.7 监控模式总结 3.监控机制 3.1 探针和内省 3.2 拉取和推…

视觉大模型应该长什么样

背景 最近朋友圈一直可以看到一个论调&#xff0c;视觉没有一个chatgpt一样强大的模型。似乎确实如此&#xff0c;视觉确实是缺一个通用能力的大模型&#xff1b;有些小伙伴可能就会讲了数据怎么能讲没有大模型&#xff1a;diffusion、della、muse、sam、controlnet一堆的大模…

springboot在启动时做点什么

Component public class ApplicationInitListener implements ApplicationListener<ContextRefreshedEvent> {Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {System.out.println("ContextRefreshedEvent.....容器初始化完…

Java 集合继承关系图

Java 容器类库的用途是“保存对象”&#xff0c;并划分为两大类,序列Collection和健值对 Map Collection接口&#xff1a;一个独立元素的序列&#xff0c;衍生的2个子类接口 List接口&#xff1a;存储有序的、可重复的数据 实现类: ArrayList、LinkedList、Vector Set接口&am…

SSMP整合案例(9) 统一表现层数据返回格式

上文 SSMP整合案例(8) Restful开发表现层接口 我们就已经是把表现层的接口写完了 但是 我们会发现 现在前端人员拿到我们的数据 格式看着非常的乱 我们 数据库 添加 修改 删除 就是但数据的格式 一个 布尔值 查询 就是 查多个 一个集合 查询 全部 则就是 一个对象的格式 还有分…

Linux 学习记录41(C++篇)

Linux 学习记录41(C篇) 本文目录 Linux 学习记录41(C篇)一、C中的引用1. 引用的定义2. 引用的注意事项3. 引用的基本使用4. 引用作为函数的入口参数5. 引用作为函数的返回值6. 常引用7. 结构体引用8. 指针和引用的区别 二、C中的动态内存分配1. new关键字(1. 申请单个类型的空间…

AI建模工具对比:如何选择适合你的工具套件

在人工智能&#xff08;AI&#xff09;的浪潮下&#xff0c;越来越多的企业和科研机构开始应用AI技术进行建模和分析。然而&#xff0c;选择哪种AI建模工具套件一直是一个让人挠头的问题。市面上存在着众多的AI建模工具&#xff0c;它们各有特点和优势&#xff0c;但如何找到适…

SpringBoot启动失败,也不报错

1&#xff09;将启动类添加try-catch捕获信息 在springboot的启动类中添加try-catch即可出现具体错误信息&#xff1b; try {SpringApplication.run(ConverterApplication.class, args);} catch (Exception e) {System.out.println("e.getMessage() " e.getMessage…

海运费查询:了解国际海运费的方法与注意事项

国际贸易中&#xff0c;海运是一种常见的货物运输方式。而对于企业或个人来说&#xff0c;了解和查询国际海运费是非常重要的。本文将介绍一些查询国际海运费的方法和注意事项&#xff0c;帮助您更好地掌握海运费用信息。 一、国际海运费的计算方法 FCL&#xff08;整箱&#…

祖冲之算法

祖冲之算法 1.题目描述 π 3.1415926~3.1415927之间 4/1-4/34/5-4/74/9-4/114/13.......... 通过关系,来计算 运算多少次之后,才会得到3.1415926~3.1415927之间2.代码 public class Main2 {public static void main(String[] args) {double ltargetPi3.1415926;double rtarg…

两两交换链表中的节点(LeetCode 24)

题目 24. 两两交换链表中的节点 思路 最开始自己画&#xff0c;越画越复杂比较复杂&#xff0c;写不出来&#xff01;&#xff08;呜呜&#xff09;去看了解题思路&#xff0c;发现只需要三步。&#xff0c;按以下思路写了代码&#xff0c;循环停止那里的条件我还以有更好的写…

android逆向开发之Frida逆向基础

Frida是一款功能强大的动态分析和逆向工程工具&#xff0c;可用于在运行时修改和监控应用程序。它支持多个平台&#xff0c;包括Android、iOS、Windows、macOS等&#xff0c;提供了JavaScript API&#xff0c;使用户能够在目标应用程序中直接执行自定义的脚本代码。 基础知识 …

CSS_高度自动过渡 auto height

方法一 grid 布局中的 fr 单位&#xff08;推荐使用&#xff09; <div class"wrap"><button class"trigger">鼠标放上来试试</button><div class"grid"><div><p>高度自动过渡</p></div></d…

leedcode-只出现一次的数字-异或

题目 题目 代码 class Solution { public:int singleNumber(vector<int>& nums) {int ansnums[0];for(int i1;i<nums.size();i){ansans^nums[i];}return ans;} };