精华内容
下载资源
问答
  • iOS 7.0之前用sizeWithFont:(计算的不是很准确)CGFloat width1=[(NSString *)obj sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(1000, FONTHEIGHT)].width;iOS 7.0之后用 ...

    iOS 7.0之前用sizeWithFont:(计算的不是很准确)

    CGFloat width1=[(NSString *)obj sizeWithFont:[UIFont systemFontOfSize:16] constrainedToSize:CGSizeMake(1000, FONTHEIGHT)].width;

    iOS 7.0之后用 boundingRectWithSize:

    返回文本绘制所占据的矩形空间。

    CGFloat width1=[(NSString *)obj boundingRectWithSize:CGSizeMake(1000, FONTHEIGHT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} context:nil].size.width;

    obj 是指要计算显示宽度的字符串

    boundingRectWithSize 表示计算的宽高限制

    计算高度时,需要宽度固定:CGSizeMake(1000, CGFLOAT_MAX)

    这里的1000也可以用已经确定的控件的宽度替代self.label.width

    计算结果表示在宽度最多为1000高度不限时,显示完全字符串需要的高度

    计算宽度时,需要高度固定:CGSizeMake(CGFLOAT_MAX, 21)

    同理21也可以用已知高度替换:self.label.height

    计算结果表示在高度不超过21时,将给定的字符串现实完全需要的宽度

    options是文本绘制的附加选项

    NSStringDrawingUsesLineFragmentOrigin 默认基线

    attributes字典格式,限定字符串显示的样式,一般限制字体较多

    @{NSFontAttributeName:[UIFont systemFontOfSize:16]}

    context包括一些信息,例如如何调整字间距以及缩放。最终,该对象包含的信息将用于文本绘制。一般写nil。

    特殊情况

    1、如果使用上述方法计算出结果后,将字符串赋值给UILabel显示,会遇到“宽度计算感觉是够的,但是字符串就是没显示完全”的情况。

    这种情况是由于计算的结果是默认贴边显示时的宽度,但UILabel 自带内边距效果,且没有直接的属性可以设置内边距的值(安卓有...),所以有的字符串会显示不完全。

    经测试:iPhoneX不会有这种问题(可能高级系统UILabel没有内边距了?),Xcode9.2上用xib试验,UILabel的左右内边距都是0.5的样子

    解决办法一:手动+5(大于左右内边距之和,且小于一个字的宽度/高度)

    解决办法二:就是网上查到的自定义UILabel,重写方法

    #import

    //.h文件

    @interface LyLabel : UILabel

    @property (nonatomic, assign) UIEdgeInsets textInsets; // 控制字体与控件边界的间隙

    @end

    //.m文件

    #import "LyLabel.h"

    @implementation LyLabel

    - (instancetype)init {

    if (self = [super init]) {

    _textInsets = UIEdgeInsetsZero;

    }

    return self;

    }

    //重写方法

    - (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {

    _textInsets = UIEdgeInsetsZero;

    }

    return self;

    }

    - (void)drawTextInRect:(CGRect)rect {

    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, _textInsets)];

    }

    @end

    具体应用:

    LyLabel *testLabel = [[LyLabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.f, 24.0f)];

    testLabel.backgroundColor = [UIColor whiteColor];

    testLabel.textColor = [UIColor blackColor];

    testLabel.font = [UIFont systemFontOfSize:16.0f];

    testLabel.textInsets = UIEdgeInsetsMake(0.f, 15.f, 0.f, 0.f); // 设置左内边距(上、左、下、右)

    总结一下,方便以后查看QAQ

    展开全文
  • 最近项目有个需求要用js计算一串字符串写入到localStorage里所占内存,众所周知,js是使用Unicode编码。而Unicode实现有N种,其中用最多就是UTF-8和UTF-16。因此本文只对这两种编码进行讨论。UTF-8(8-...

    最近项目有个需求要用js计算一串字符串写入到localStorage里所占的内存,众所周知的,js是使用Unicode编码的。而Unicode的实现有N种,其中用的最多的就是UTF-8和UTF-16。因此本文只对这两种编码进行讨论。

    UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,可以表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII相容,使用一至四个字节为每个字符编码

    其编码规则如下:

    字符代码在000000 – 00007F之间的,用一个字节编码;

    000080 – 0007FF之间的字符用两个字节;

    000800 – 00D7FF 和 00E000 – 00FFFF之间的用三个字节,注: Unicode在范围 D800-DFFF 中不存在任何字符;

    010000 – 10FFFF之间的用4个字节。

    而UTF-16 则是定长的字符编码,大部分字符使用两个字节编码,字符代码超出 65535 的使用四个字节,如下:

    000000 – 00FFFF 两个字节;

    010000 – 10FFFF 四个字节。

    一开始认为既然页面用的是UTF-8编码,那么存入localStorage的字符串,应该也是用UTF-8编码的。但后来测试发现,明明计算出的size是不到5MB,存入localStorage却抛异常了。想了想,页面的编码是可以改的。如果localStorage按照页面的编码存字符串,不就乱套了?浏览器应该都是使用UTF-16编码的。用UTF-16编码计算出5MB的字符串,果然顺利写进去了。超过则失败了。

    好了,附上代码实现。计算规则就是上面写的,为了计算速度,把两个for循环分开写了。

    /**

    * 计算字符串所占的内存字节数,默认使用UTF-8的编码方式计算,也可制定为UTF-16

    * UTF-8 是一种可变长度的 Unicode 编码格式,使用一至四个字节为每个字符编码

    *

    * 000000 - 00007F(128个代码) 0zzzzzzz(00-7F) 一个字节

    * 000080 - 0007FF(1920个代码) 110yyyyy(C0-DF) 10zzzzzz(80-BF) 两个字节

    * 000800 - 00D7FF

    00E000 - 00FFFF(61440个代码) 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 三个字节

    * 010000 - 10FFFF(1048576个代码) 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 四个字节

    *

    * 注: Unicode在范围 D800-DFFF 中不存在任何字符

    * {@link http://zh.wikipedia.org/wiki/UTF-8}

    *

    * UTF-16 大部分使用两个字节编码,编码超出 65535 的使用四个字节

    * 000000 - 00FFFF 两个字节

    * 010000 - 10FFFF 四个字节

    *

    * {@link http://zh.wikipedia.org/wiki/UTF-16}

    * @param {String} str

    * @param {String} charset utf-8, utf-16

    * @return {Number}

    */

    var sizeof = function(str, charset){

    var total = 0,

    charCode,

    i,

    len;

    charset = charset ? charset.toLowerCase() : '';

    if(charset === 'utf-16' || charset === 'utf16'){

    for(i = 0, len = str.length; i < len; i++){

    charCode = str.charCodeAt(i);

    if(charCode <= 0xffff){

    total += 2;

    }else{

    total += 4;

    }

    }

    }else{

    for(i = 0, len = str.length; i < len; i++){

    charCode = str.charCodeAt(i);

    if(charCode <= 0x007f) {

    total += 1;

    }else if(charCode <= 0x07ff){

    total += 2;

    }else if(charCode <= 0xffff){

    total += 3;

    }else{

    total += 4;

    }

    }

    }

    return total;

    }

    转载自AlloyTeam:http://www.alloyteam.com/2013/12/js-calculate-the-number-of-bytes-occupied-by-a-string/

    展开全文
  • 不同编码字节不一样【以下列举常见三种编码形式】: GBK:一个汉字等于2字节,一个字母就等于1个字节,操作符等于1个字节。 UTF-8:一个汉字等于3个字节,中文句号‘。’等于3个字节,一个字母等于1字节,英文...

    不同的编码字节个数不一样的【以下列举常见三种编码形式】:

    GBK:一个汉字等于2字节,一个字母就等于1个字节,操作符等于1个字节。
    UTF-8:一个汉字等于3个字节,中文句号‘。’等于3个字节,一个字母等于1字节,英文的句号‘.’等于1个字节
    Unicode:一个汉字等于4个字节,都是等于2个字节【英语,数字,操作符[。,%,&]等的呢】

    public class zijie {
        public static void main(String[] args) {
            // 得到当前的系统属性
            String encoding = System.getProperty("file.encoding");
            System.out.println("当前编码:" + encoding);
            try {
                String str = "([0.04245922968394873,0.35328006651790006,6.160877241621716E-4,3.2568745892276585E-4,4.082970851109664E-4,0.33464432678726974,5.467903501318759E-4,0.2677195143925537],ListBuffer(((6.226147480536253,289),27), ((5.971384772976431,595),53), ((3.216778047230726,7840),54)))";
    //            String str = "JTI4JTVCMC4wNDI0NTkyMjk2ODM5NDg3MyUyQzAuMzUzMjgwMDY2NTE3OTAwMDYlMkM2LjE2MDg3NzI0MTYyMTcxNkUtNCUyQzMuMjU2ODc0NTg5MjI3NjU4NUUtNCUyQzQuMDgyOTcwODUxMTA5NjY0RS00JTJDMC4zMzQ2NDQzMjY3ODcyNjk3NCUyQzUuNDY3OTAzNTAxMzE4NzU5RS00JTJDMC4yNjc3MTk1MTQzOTI1NTM3JTVEJTJDTGlzdEJ1ZmZlciUyOCUyOCUyODYuMjI2MTQ3NDgwNTM2MjUzJTJDMjg5JTI5JTJDMjclMjklMkMlMjAlMjglMjg1Ljk3MTM4NDc3Mjk3NjQzMSUyQzU5NSUyOSUyQzUzJTI5JTJDJTIwJTI4JTI4My4yMTY3NzgwNDcyMzA3MjYlMkM3ODQwJTI5JTJDNTQlMjklMjklMjk=";
                int len = str.getBytes().length;
                System.out.println("1.按操作系统默认编码来编码:" + len);
    
                len = str.getBytes("GBK").length;
                System.out.println("2.GBK编码的字节数:"+ len);
    
                len = str.getBytes("UTF-8").length;
                System.out.println("3.UTF-8编码的字节数:" + len);
    
                len = str.getBytes("Unicode").length;
                System.out.println("4.Unicode编码的字节数:" + len);
                /*
                 * 当前编码:UTF-8
                 * 1.按操作系统默认编码来编码:5
                 * 2.GBK编码的字节数:4
                 * 3.UTF-8编码的字节数:5
                 * 4.Unicode编码的字节数:8
                 */
    
            }  catch ( java.io.UnsupportedEncodingException e)  {
                System.out.println(e.getMessage().toString());
            }
        }
    }
    
    

    在这里插入图片描述

    另外博主收藏这些年来看过或者听过的一些不错的常用的上千本书籍,没准你想找的书就在这里呢,包含了互联网行业大多数书籍和面试经验题目等等。有人工智能系列(常用深度学习框架TensorFlow、pytorch、keras。NLP、机器学习,深度学习等等),大数据系列(Spark,Hadoop,Scala,kafka等),程序员必修系列(C、C++、java、数据结构、linux,设计模式、数据库等等)以下是部分截图

    更多文章见本原创微信公众号「五角钱的程序员」,我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活。关注回复【电子书】即可领取哦

    在这里插入图片描述
    在这里插入图片描述

    给大家推荐一个Github,上面非常非常多的干货:https://github.com/XiangLinPro/IT_book

    Promise yourself to accept life as it comes
    and truly make each day special.

    展开全文
  • 12.0.0 字符串12.1.0 二维数组基本使用12.1.1 二维数组声明二维数组就是一个有行有列表格。我们声明一个二维数组,就相当于在内存中创建了指定行指定列一个表格来存储数据。二维数组首先是一个数组,所以它...

    12.0.0 字符串

    12.1.0 二维数组的基本使用

    12.1.1 二维数组的声明

    二维数组就是一个有行有列的表格。

    我们声明一个二维数组,就相当于在内存中创建了指定行指定列的一个表格来存储数据。

    二维数组首先是一个数组,所以它符合数组的一般特点:

    • 元素的类型相同
    • 存储的数据的个数固定
    • 方便管理数据

    另外它也有自己独特的特点:

    • 二维数组是一个有行有列的表格
    • 使用单元格来存储数据,单元格就是二维数组的元素

    声明二维数组的语法:

    元素类型 数组名[行数][列数];

    例如:

    int arr[3][4];

    表示在内存中声明了一个二维数组,这个二维数组的名字叫做arr;

    这个二维数组表示1个3行4列的表格;

    每个单元格就是这个二维数组的一个元素;

    每个元素的类型是int类型。

    几个术语:

    • 元素:就是这个二维数组表格的每一个单元格。
    • 下标:二维数组的元素的下标有两个,一个是行下标,一个是列下标。
    • 长度:一般把单元格的个数叫做二维数组的长度。行*列

    12.1.2 如何往二维数组中存储数据

    对于二维数组,在存储数据的时候,必须要确定到底要存储到哪一个元素之中。而下标是用来确定二维数组中的元素的,所以我们可以用下标来表示每一个元素的在二维数组中的位置,进而用来为元素赋值。唯一要注意的是二维数组的下标有两个,行下标和列下标:

    二维数组名[行下标][列下标] = 数据;

    int arr[3][4];
    int arr[1][2] = 100;

    表示将100赋值给arr这个二维数组的第1行第2列的元素。

    注意:

    • 赋值的数据类型应该和定义的二维数组的类型一致,否则将会自动产生类型转换;
    • 行、列下标不要越界,否则可能会造成程序崩溃。

    12.1.3 如何从二维数组中取出数据

    还是通过二维数组的下标来取出其元素的数据,唯一要注意的是下标有两个:

    二维数组名[行下标][列下标];

    注意:行列下标不要越界。

    如何遍历二维数组的所有元素?

    代码例子:

    for (int i = 0; i < 行数; i++)
    {
     for (int j = 0; j < 列数; j++)
     {
       printf(%dt,arr[i][j]);
     }
    }

    12.1.4 二维数组的注意事项

    关于二维数组的行数和列数:

    • 在声明二维数组的时候,必须要指定行数和列数
    • 行数和列数可以是变量、常量、宏、表达式,也可以是1或0.
    • 行数和列数不能是小数和负数

    关于二维数组的元素的默认值:

    如果我们声明一个二维数组的时候,没有为其赋值,那么这个二维数组中的元素是有值的,这些值都是垃圾值。

    12.1.5 二维数组的初始化

    二维数组的全部初始化有下列几种方法:

    • 先声明,再使用下标来初始化
    • 在声明的同时,就初始化数组的每一个元素:
    int arr[3][4] = 
    {
     {10,20,30,40},
     {50,60,70,80},
     {90,100,110,120}
    };

    这种方式初始化时可以参略行数

    • 可以参略里面的大括号,编译器会自己根据数据的多少自动判断行数和列数:
    int arr[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120};

    这种方式也可以参略行数

    部分初始化的方法有如下几种:

    • int arr[3][4] = {{10},{20},{30}};

    初始化指定行的数据,那么其他的元素就会被自动初始化为0.

    10 0 0 0

    20 0 0 0

    30 0 0 0

    • int arr[3][4] = {10,20,30,40,50};

    按照顺序去初始化每一个元素,其他的元素的值就会被自动初始化为0.

    10 20 30 40

    50 0 0 0

    0 0 0 0

    • 如果省略了行数,也会被系统允许,但是实际计算的行数会根据实际输入的数据个数来决定:
    int arr[][4] = {10,20,30,40,50};

    系统会根据输入的数据个数来计算行数,上面的数据有5个,而列数已知是4列,所以系统会认为这个二维数组是2行4列。

    10 20 30 40

    50 0 0 0

    • 给指定的行初始化,其他的元素自动初始化为0:
    int arr[3][4] = {[1]={10,20,30,40},[2]={50,60,70,80}};

    这个时候这个二维数组的内容如下:

    0 0 0 0

    10 20 30 40

    50 60 70 80

    • 给指定的元素赋值,其他的元素自动初始化为0:
    int arr[3][4] = {[0][1]=20,[1][3]=60};

    这个时候这个二维数组的内容如下:

    0 20 0 0

    0 0 0 60

    0 0 0 0

    12.1.6 二维数组的应用场景

    某公司,有三个销售小组,每组有4个人

    要求用二维数组将其销售成绩存储起来

    然后计算:1. 销售之王 2. 求每个小组的平均销售额

    代码例子如下:

    int arr[3][4] = 
    {
     {45,67,34,56},
     {45,23,4,57},
     {21,34,89,77}
    };
    int max = INT32_MIN;
    for (int i = 0;i < 3;i++)
    {
     for (int j = 0;j < 4;j++)
     {
       if(arr[i][j] > max)
       {
         max = arr[i][j];
       }
     }
    }
    printf(“销售之王的销售额是:%d万n,max);
    for (int i = 0;i < 3;i++)
    {
     int sum = 0;
     for (int j = 0;j < 4;j++)
     {
       sum += arr[i][j];
     }
     printf(“第%d组的平均销售成绩是%d万n,i+1,sum/4);
    }

    什么时候要使用二维数组?

    当有类似于表格形式的数据需要处理的时候,就可以使用二维数组。

    12.2.0 二维数组在内存中的形式

    12.2.1 二维数组在内存中的存储

    一维数组的元素只需要1个下标就可以确定;

    二维数组的元素需要2个下标才可以确定。

    一维数组像一条线,要确定一条线上的1个点只需要1个下标就可以了;

    二维数组像一个面,要确定一个面上的一个点需要两个下标才可以。

    那么二维数组是如何在内存中申请空间的呢?

    举例:

    int arr[2][3];
    • 从高地址向低地址申请了连续的(行*列*每个元素占用的字节数)个字节空间
    • 第0行是在低字节,第0行第0列的元素是在这个数组的内存地址中最低字节。

    所以,二维数组在内存中仍然是一块连续的空间,并不是一个表格。

    二维数组的本质其实是多个一维数组,在内存中占用了连续的空间。

    12.2.2 二维数组的地址和行列计算

    组成二维数组的低字节的地址就是这个二维数组的地址,也就是第0行的地址,也就是第0行的第0个元素的地址。

    获取二维数组的内存地址可以用如下代码:

    printf(%pn,arr);
    printf(%pn,&arr[0][0]);
    printf(%pn,arr[0]); 

    //因为第0行就是一个一维数组,这个数组名就是其地址

    所以:

    二维数组的地址=二维数组名=二维数组的0行的地址=二维数组的0行0列元素的地址=二维数组低字节的地址

    • 二维数组的长度计算:

    二维数组的长度是这个二维数组的所有元素的个数

    用二维数组占用的总的字节数 / 每一个元素所占用的字节数

    例子:sizeof(arr) / sizeof(arr[0][0]);
    • 二维数组的行数计算:

    二维数组的每一行占用的字节数是一样的,所以:

    用总的字节数 / 每一行占用的字节数 = 行数

    例子:sizeof(arr) / sizeof(arr[0]);
    • 二维数组的列数计算:

    每一行的总字节数 / 每一个元素的字节数 = 列数

    例子:sizeof(arr[0]) / sizeof(arr[0][0]);

    注意:

    • 在声明二维数组的同时使用大括号初始化数组的元素,这个时候行数可以省略,但是列数不可以省略。
    • 在声明二维数组的同时不初始化数组的元素时,行数和列数都不可以省略。

    12.3.0 二维数组与函数

    12.3.1 使用二维数组作为参数的函数

    • 如果函数的参数时一个一维数组,那么我们在传递参数的时候,可以传递二维数组的某一行,因为二维数组的行其实就是一个一维数组。
    • 二维数组也可以作为函数的参数。

    例子:

    void test(int arr[3][4])
    {
     内代码省略;
    }
    int arr[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120};
    test (arr);
      • 如果函数的参数是一个二维数组,那么在调用的时候,实参也必须是一个同类型的二维数组
      • 当二维数组作为函数的参数的时候,会丢失这个二维数组的行数和列数信息。

    因为声明参数二维数组的时候,并不是去创建一个二维数组,而是创建1个用来存储数组地址的指针变量,而指针变量是占据8个字节的。所以这个时候,在函数的内部使用sizeof来计算参数二维数组的占用字节的时候得到的结果永远都是8个字节。

      • 当二维数组作为函数的参数的时候,行数可以省略,但是列数不能省略。并且实参的行数可以任意,但是列数必须和形参的列数保持一致。
      • 解决方法是:让调用者将二维数组的行数和列数都传递到函数内部中来。所以至少还要加上两个参数,一个是行(row),一个是列(column)。

    实参二维数组的列数必须要和形参二维数组的列数一致。在写参数的时候,先写行数和列数,最后再写二维数组,然后二维数组的列数用参数指定。

    例如:void test(int rows,int cols,int arr[][cols]);

    这个时候,传递的二维数组的行数和列数就基本上是任意指定的了,可以在不修改函数的前提下在main函数内随意填写实参二维数组的行数和列数。

    案例代码:

    从控制台接收用户输入1个二维数组的行数和列数:

    1. 然后创建这个二维数组;
    2. 写一个函数,为这个二维数组的元素赋值:元素的值=(行*列)+
      10;
    3. 再写一个函数,打印二维数组的所有元素。
    void setValue(int rows,int cols,int arr[][cols])
    {
     for (int i = 0; i < rows; i++);
     {
     for (int j = 0; j < cols; j++);
     {
       arr[i][j] = (i*j)+10;
     }
     }
    }
    
    void getValue(int rows,int cols,int arr[][cols])
    {
     for (int i = 0; i < rows; i++)
     {
       for (int j = 0; j <cols; j++)
       {
         printf(%d ,arr[i][j]);
       }
     }
     printf(n);
    }
    int main()
    {
     int rows = 0, cols = 0;
     printf(Please input Rows & Columns:);
     scanf(%d%d,&rows,&cols);
     int arr[rows][cols];
     setValue(rows, cols, arr);
     getValue(rows, cols, arr);
     return 0;
    }

    12.4.0 字符串

    12.4.1 字符数组

    • 声明字符数组

    char chs[4];

    表示声明了1一个长度为4的字符数组,这个数组的名字叫chs,最多可以存储4个字符。

    • 字符数组的取值和遍历

    同样使用for循环来遍历和取值

    • 字符数组的每一个元素本质上就是一个char变量,所以字符数组中的元素仍然不可以存储中文
    • 关于字符数组的默认值问题:

    声明一个字符数组,不给这个数组的元素赋值,那么这个字符数组的元素是有值的,值是垃圾值。

    在声明字符数组的同时,如果初始化了部分元素,那么其他元素会被初始化为’0’,0的ASCII码为0。

    12.4.2 C语言存储字符串数据的方法

    之前学习的数据类型有int、double、float、char,但是实际上,还有一种数据是无法存储的,类似于Jack、5354_abc等。

    像这样的数据,我们叫做字符串。

    在C语言中字符串数据必须要用双引号引起来。

    “Jack” “5354_abc”

    那如何存储字符串数据呢?

    分析一下,Jack其实是由四个字符组成的,所以我们可以用1个字符数组来存储字符串数据,把组成这个字符串数据的每一个字符存储到字符数组中去。

    char name[4];
    name[0]=J;
    name[1]=a;
    name[2]=c;
    name[3]=k;

    所以:

    C语言中存储字符串数据的原理是:将字符串数据的每一个字符存储到字符数组中,并在后面追加一个’0’代表字符串存储完毕。

    • 存储字符串的方式:
    1. a.最根本的方式:
    char name[5]={J,a,c,k,0};

    将字符串的每一个字符存储到字符数组中,在后面追见一个’0’代表存储结束

    char name[]={J,a,c,k,0};
      1. b.简写的方式:
    char name[]={Jack};

    系统自动的会将这个字符串中的每一个字符存储到字符数组中,并自动追加一个’0’

      1. c.最常用的方式:
    char name[]=Jack;

    系统自动的会将这个字符串中的每一个字符存储到字符数组中,并自动追加一个’0’

    12.4.3 使用字符数组存储字符串的注意事项

    • 如果使用字符数组存储字符串数据的时候,没有指定长度,那么这个字符数组的长度=字符串的长度+1;
    • 如果指定了字符数组的长度,那么这个字符数组的长度就是指定的长度;
    • 如果指定了字符数组的长度小于等于了字符串的长度,那么这个时候会出现存储不下的情况,系统会报错;
    • 如果在声明一个字符数组的同时就初始化一个字符串给这个数组,这个时候是可以使用中文的;

    12.4.4 字符串的输出

    虽然可以使用for循环来打印输出字符串,但是这样的操作过于繁琐和没有效率。

    C语言系统中可以使用%s的格式控制符来输出存储在字符数组中的字符串数据。

    例子:printf(%sn,name);

    %s的原理:从给定的数组的地址开始1个字节1个字节的输出,直到遇到’0’为止。

    12.4.5 如何从控制台接收输入的字符串

    使用scanf函数可以实现从控制台接收输入的字符串。

    1. 1.先准备一个字符数组来保存用户输入的字符串数据;
    2. 2.使用scanf函数接收用户输入字符串数据并存储到指定的字符数组中;

    例子:

    char str[10];
    scanf(%s,str);

    注意:

    • 如果输入的字符串数据长度大于声明的字符数组长度,系统会报错崩溃;
    • 如果在输入字符串的时候,如果输入了空格,系统会认为输入结束,后面的内容会被忽略。

    12.4.6 字符串的长度计算

    字符串的长度不能使用sizeof来计算的,因为存储字符串的字符数组往往要比字符串长,甚至可能要长出不少。因为有时候数组定义的长度要超出字符串的长度很多。

    所以正确的计算方式应该是从这个字符数组的第一个字节开始计数,直到遇到’0’为止。

    代码如下:

    char name[100] = Jack;
    int len = 0;
    while (name[len] != 0)
    {
     len++;
    }

    12.4.7 与字符串相关的常用函数

    • puts()函数

    作用:用来输出字符串

    语法格式:puts(字符数组名);

    优点:简单,输入完毕会自动换行

    缺点:只能输出字符串,也不可以使用占位符

    • gets()函数

    作用:从控制台接收用户输入1个字符串数据

    语法格式:gets(字符数组名);

    优点:当用户输入的字符串数据中有空格时,可以连同空格一起接收

    缺点:和scanf函数一样,存在超长度的情况,不安全

    ————以上两个函数是声明在stdio.h文件中————

    ————以下四个函数数声明在string.h文件中————

    • strlen()函数

    作用:得到存储在字符数组中字符串数据的长度

    语法格式:strlen(字符数组名);

    注意:在声明变量接收strlen函数的结果时,要使用unsigned long类型。

    • strcmp()函数

    作用:用来比较两个字符串的大小

    语法格式:strcmp(字符数组名1,字符数组名2);

    如果返回的结果是负数,表示字符串1比字符串2小;

    如果返回的结果是正数,表示字符串1比字符串2大;

    如果返回的结果是0,表示相同。

    比较的规则:比的是相同位置的字符的ASCII码的大小

    • strcpy()函数

    作用:把存储在1个字符数组中的字符串数据拷贝到另外一个字符数组中存储。

    语法格式:strcpy(字符数组名1,字符数组名2);

    这个表示将字符数组2的内容拷贝到字符数组1中去。

    可能会产生因为两个字符数组长度不一样导致运行崩溃的问题。

    • strcat()函数

    作用:把存储在字符数组2的字符串数据2链接到存储字符串1的字符数组1后面

    语法格式:strcat(字符数组名1,字符数组名2);

    也可能会产生两个字符串因合并后超出字符串的长度定义而运行崩溃的问题。

    12.4.8 走出迷宫

    代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #define rows 8
    #define cols 8
    
    //用二维数组将地图保存起来
    char map[rows][cols] =
    {
     {'#','#','#','#','#','#','#','#'},
     {'#','o','#',' ',' ',' ','#','#'},
     {'#',' ','#',' ','#',' ',' ','#'},
     {'#',' ','#',' ',' ','#',' ','#'},
     {'#',' ','#','#',' ','#',' ','#'},
     {'#',' ','#','#',' ','#',' ','#'},
     {'#',' ',' ',' ',' ','#',' ','#'},
     {'#','#','#','#','#','#',' ','#'},
    };
    
    //保存小人的初始坐标
    int personRow = 1;
    int personCol = 1;
    
    /// 打印地图
    void showMap(void);
    
    /// 接收用户输入小人方向
    char enterDirection(void);
    
    void moveUp(void);
    
    void moveDown(void);
    
    void moveLeft(void);
    
    void moveRight(void);
    
    int main(int argc, const char * argv[])
    {
     while (map[7][6] != 'o' )
     {
       system("clear");
       showMap();  
       char dir = enterDirection();  
       switch (dir)
       {
         case 'a':
         case 'A':
           moveLeft();
           break;
         case 'd':
         case 'D':
           moveRight();
           break;
         case 'w':
         case 'W':
           moveUp();
           break;
         case 's':
         case 'S':
           moveDown();
           break;
         case 'q':
         case 'Q':
           printf("已结束游戏!n");
           return 0;
           break;
       }
     }
     printf("恭喜你!已走出迷宫!n");
     return 0;
    }
    
    void showMap()
    {
     for (int i =0; i < rows; i++)
     {
       for (int j = 0; j < cols; j++)
       {
         printf("%c ",map[i][j]);
       }
       printf("n");
     }
    }
    
    char enterDirection()
    {
     printf("请输入小人的前进方向:w - 上 s - 下 a - 左 d - 右 q - 结束游戏 n");
     char dir = 'a';
     rewind(stdin);
     scanf("%c",&dir);
     return dir;
    }
    
    void moveUp()
    {
     int nextRow = personRow - 1;
     int nextCol = personCol;
     if (map[nextRow][nextCol] == ' ')
     {
       map[nextRow][nextCol] = 'o';
       map[personRow][personCol] = ' ';
       personRow = nextRow;
       personCol = nextCol;
     }
    }
    
    void moveDown()
    {
     int nextRow = personRow + 1; 
     int nextCol = personCol; 
     if (map[nextRow][nextCol] == ' ')
     {
       map[nextRow][nextCol] = 'o';
       map[personRow][personCol] = ' ';
       personRow = nextRow;
       personCol = nextCol;
     }
    }
    
    void moveLeft()
    {
     int nextRow = personRow;
     int nextCol = personCol - 1;
     if (map[nextRow][nextCol] == ' ')
     {
       map[nextRow][nextCol] = 'o';
       map[personRow][personCol] = ' ';
       personRow = nextRow;
       personCol = nextCol;
     }
    }
    
    void moveRight()
    {
     int nextRow = personRow;
     int nextCol = personCol + 1;
     if (map[nextRow][nextCol] == ' ')
     {
       map[nextRow][nextCol] = 'o';
       map[personRow][personCol] = ' ';
       personRow = nextRow;
       personCol = nextCol;
     }
    }

    完整学习笔记会完全记录在我的个人网站和知乎上,免费的pdf和epub版本将来会在我的网站提供下载链接,敬请期待!

    此外,本栏目的全部内容已发表在Apple Books Store上,如果有条件的读者(Apple Books在中国大陆地区没有服务)可以点击如下链接购买支持我!谢谢!

    Apple Books Store的版本支持目录索引,以及快速查阅,稍后的版本还将支持函数及关键字速查。

    Apple Books Store商店链接:

    ‎简明C语言学习指南books.apple.com
    26580dfc31b7c5652124085346e51cbe.png

    我的个人网站:https://beautylife.pub

    美丽人生工作室beautylife.pub

    C语言学习笔记的网址:(持续更新)

    C语言学习 - BeautyLife Studiobeautylife.pub
    2f2df131edf433c2145081bbf19d704b.png

    感谢提供我个人网站服务器空间的优网主机:

    优网主机 - 安全稳定、简单易用!my.youwebcloud.com
    6906e3266f6c7ef80833020b86cf58cd.png
    展开全文
  • 这样一个字节可以表达28次方(256)个状态,大于256个状态怎么表示?那就字。(3)字:2个字节组成一个字,有16个位。这样一个字可以表达216次方(65536)个状态,大于65536个状态怎么表示? 那就用 双字。(4)双字:2个...
  • 学习PLC编程过程中不可避免会接触到数据运算、比较等操作,当两个操作类型不同时就需要进行转换,所以数据转换指令也是编程重要指令。但是很多人往往不是太了解ASCII字符字符与数据之间如何转换,本文就着重...
  • 寻址方式 (这个地方要分清楚,PLC存储空间大小(位字节字双字BIT BYTE WORD DWORD)、储存器类型(西门子DIDQAIAQMSMVLTCHTHC区;三菱XYMDTCRVZ区)、数据类型(INT16 DINT32 REAL STRING WORD16 DWOR...
  • 本文采用案例分析方法来与各位分享,希望能够对相关读者有所帮助,下面我们进入正文。硬件连接三菱PLC FX系列可以通过自身编程口和计算机通信,也可通过通信口和计算机通信。通过编程口,一台计算机只能和一台...
  • 工业控制用计算机。PLC基本构成其基本构成有 电源、CPU、储存器、输入单元、输出单元、通信接口、扩展接口。a)电源:PLC供电,可以是220VAC或者24VDC,CPU处理单元所需要电源为5VDC。b)CPU(中央处理单元),...
  • python思维导图入门第三篇,变量,常量,编码,字符串set 是一组key集合,但不存储value由于key不能重复,在set中,没有重复keyset是无序重复元素在set中自动被过滤set可以看成数学意义上无序和无重复元素...
  • 基础一、 选择题1、 世界上首先实现存储程序电子数字计算机是____。A、ENIAC B、UNIVAC C、EDVAC D、EDSAC 2、计算机科学奠基人是____。 A、查尔斯.巴贝奇 B、图灵 C、阿塔诺索夫 D、冯.诺依曼2、 世界上...
  • 寻址方式 (这个地方要分清楚,PLC存储空间大小(位字节字双字BIT BYTE WORD DWORD)、储存器类型(西门子DIDQAIAQMSMVLTCHTHC区;三菱XYMDTCRVZ区)、数据类型(INT16 DINT32 REAL STRING WORD16 DWORD32 BOOL TIME D.....
  • 西门子S7-1200 紧凑型PLC在当前市场中有着广泛应用,由于其性价比高,所以常被用作小型自动化控制设备控制器,这也使得它经常与第三方设备(扫描枪、打印机等设备进行通讯。因为没有第三方设备,这里就以...
  • Unicode是什么计算机存储基本单位是 八位字节 ,由 8 个比特位组成,简称 字节 。由于英文只由 26 个字母加若干符号组成,因此英文字符可以直接用 字节 来保存。其他诸如中日韩等语言,由于字符众多,则不得不用多...
  • 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理...
  • 1 2和’2’是不是一回事2和’2’根本不是一回事,2是数字,’2’是一个字符,他们在计算机内存中占用一个字节,但是实际意义根本不一样。2 23和‘23’又是怎么一回事 转载于:...
  • 中文编码是一个复杂而繁琐问题,尤其是在使用...那么C++怎么样在中英文混合字符串中分离中英文或者计算字符串长度(不是字节数)呢,那就需要彻底搞清楚编码是个怎么回事。一、ASCII 码ASCII 码,全称 America...
  • 中文编码是一个复杂而繁琐问题,尤其是在使用...那么C++怎么样在中英文混合字符串中分离中英文或者计算字符串长度(不是字节数)呢,那就需要彻底搞清楚编码是个怎么回事。一、ASCII 码ASCII 码,全称 America...
  • 输入连续或空格隔开16进制或ASCII码字符串后点击计算,可求其10进制累加值、16进制累加值、BCC校验(16进制,HEX)、BCC校验(ASCII码,HEX)、BCC校验(10进制,DEC)、BCC校验(2进制,BIN)、字节数(HEX)、字节数(DEC)等...
  • 因为sizeof运算符可以求出每个对象所占内存的字节数,并且在这些基本类型组成的数组中,每个元素所占内存空间都是相同的,因此我们可以使用 “数量 = 总价 / 单价” 这种方式来计算。 而我们的string字符串数组是可...
  • 函数LENB:返回文本字符串的字节。汉字、全角状态下的标点符号,每个字符按2个字节计算;英文字母、数字、半角状态下的标点符号,每个字符按1个字节计算。1、提取文本A列数据中文本与数字混...
  • IP地址是一个由二进制“0”和“1”组成4字节共32位字符串。 IP地址是由网络地址+主机地址组成那么可以得出网络位+主机位=32位 如何知道一个IP地址里有多少个网络位和主机位呢,那么这个由子网掩码决定...
  • 这篇文章主要讲如何使用正则匹配中文字符,中文正则表达式的匹配规则不像其他正则规则一样容易记住,下面一起看看这个中文正则表达式是怎么样的。\w匹配的仅仅是中文,数字,字母,...注:可以用来计算字符串的长度...
  • 1. bitmap和zset数据结构简介Redis中bitmap和...位只能存储0或者1,我们平时所说的字符串、数字等所有数据信息在计算机中都是通过多个0和1组合一起表示。8个位为1个字节(1B),1024个字节为1KB,1024KB是1M;也就是...
  • 我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊是还有一个编码问题。 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早计算机在设计时采用8个比特(bit)作为...
  • 常见的c++数据类型的字节数3&amp;amp;amp;gt; 一些常见windows数据类型引言windows编程常用的数据类型字符串转换成窗口句柄HWND 1&amp;amp;amp;gt; 怎么计算一个类型的范围? 以前大学学的8086是16位的...
  • 这篇文章主要讲如何使用正则...注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 更多常用正则表达式匹配规则: 英文字母:[a-zA-Z] 数字:[0-9] 匹配中文,英文字母和数字及_: //code from http:
  • 这篇文章主要讲如何使用正则匹配中文字符,中文正则表达式的匹配规则不像其他正则规则一样容易...注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1) 更多常用正则表达式匹配规则: 英文字母:[a
  • 2.15 如何确定域在结构中的字节偏移量? 2.16 怎样在运行时用名字访问结构中的域? 2.17 C语言中有和Pascal的with等价的语句吗? 2.18 既然数组名可以用作数组的基地址,为什么对结构不能这样? 2.19 程序运行...

空空如也

空空如也

1 2 3 4
收藏数 61
精华内容 24
关键字:

怎么计算字符串的字节数