c语言修改字符串c2133,通过create_string_buffer、create_unicode_buffer让C语言具备修改字符串的能力...

字符串的修改

我们知道C中不存在字符串这个概念,python中的字符串在C中也是通过字符数组来实现的。我们说在C中创建一个字符数组有两种方式:

char *s1 = "hello world";

char s2[] = "hello world";

这两种方式虽然打印的结果是一样的,并且s1、s2都指向了对应字符数组的首地址,但是内部的结构确是不同的。

1.char *s1 = "hello world";此时这个字符数组是存放在静态存储区里面的,程序编译的时候这块区域就已经确定好了,静态存储区在程序的整个运行期间都是存在的,主要用来存放一些静态变量、全局变量、常量。因此s1只能够访问这个字符数组,却不能够改变它,因为它是一个常量。而char s2[] = "hello world";,这种方式创建的字符数组是存放在栈当中的,可以通过s2这个指针去修改它。

2.char *s1 = "hello world";是在编译的时候就已经确定了,因为是一个常量。而char s2[] = "hello world";则是在运行时才确定。

3.char *s1 = "hello world";创建的字符数组存于静态存储区,char s2[] = "hello world";创建的字符数组存储于栈区,所以s1访问的速度没有s2快。

d1de7e9df5d8d2f42e87252f720727b3.png

7ad04be2f8ebaec24996f4e8e75affd5.png

所以我们说char *s这种方式创建的字符数组在C中是不能修改的,但是我们通过ctypes却可以做到对char *s进行修改:

#include

int test(char *s1, char s2[6])

{

//两种方式都进行修改

s1[0] = 'a';

s2[0] = 'a';

printf("s1 = %s, s2 = %s\n", s1, s2);

}

我们还是将C文件编译成mmp.dll

import ctypes

from ctypes import *

lib = ctypes.CDLL("./mmp.dll")

# 我们看到无论是char *s1,还是char s2[...],我们都可以使用c_char_p这种方式传递

lib.test(c_char_p(b"hello"), c_char_p(b"hello")) # s1 = aello, s2 = aello

我们看到两种方式都成功修改了,但是即便能修改,我们不建议这么做。不是说不让修改,而是应该换一种方式。如果是需要修改的话,那么不要使用c_char_p的方式来传递,而是建议通过create_string_buffer来给C语言传递可以修改字符的空间。

create_string_buffer

create_string_buffer是ctypes提供的一个函数,表示创建具有一定大小的字符缓存,就理解为字符数组即可。

from ctypes import *

# 传入一个int,表示创建一个具有固定大小的字符缓存,这里是10个

s = create_string_buffer(10)

# 直接打印就是一个对象

print(s) #

# 也可以调用value方法打印它的值,可以看到什么都没有

print(s.value) # b''

# 并且它还有一个raw方法,表示C语言中的字符数组,由于长度为10,并且没有内容,所以全部是\x00,就是C语言中的\0

print(s.raw) # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

# 还可以查看长度

print(len(s)) # 10

当然create_string_buffer如果只传一个int,那么表示创建对应长度的字符缓存。除此之外,还可以指定字节串,此时的字符缓存大小和指定的字节串大小是一致的:

from ctypes import *

# 此时我们直接创建了一个字符缓存

s = create_string_buffer(b"hello")

print(s) #

print(s.value) # b'hello'

# 我们知道在C中,字符数组是以\0作为结束标记的,所以结尾会有一个\0,因为raw表示C中的字符数组

print(s.raw) # b'hello\x00'

# 长度为6,b"hello"五个字符再加上\0一共6个

print(len(s))

当然create_string_buffer还可以指定字节串的同时,指定空间大小。

from ctypes import *

# 此时我们直接创建了一个字符缓存,如果不指定容量,那么默认和对应的字符数组大小一致

# 但是我们还可以同时指定容量,记得容量要比前面的字节串的长度要大。

s = create_string_buffer(b"hello", 10)

print(s) #

print(s.value) # b'hello'

# 长度为10,剩余的5个显然是\0

print(s.raw) # b'hello\x00\x00\x00\x00\x00'

print(len(s)) # 10

下面我们来看看如何使用create_string_buffer来传递:

#include

int test(char *s)

{

//变量的形式依旧是char *s

//下面的操作就是相当于把字符数组的索引为5到11的部分换成" satori"

s[5] = ' ';

s[6] = 's';

s[7] = 'a';

s[8] = 't';

s[9] = 'o';

s[10] = 'r';

s[11] = 'i';

printf("s = %s\n", s);

}

from ctypes import *

lib = CDLL("./mmp.dll")

s = create_string_buffer(b"hello", 20)

lib.test(s) # s = hello satori

此时就成功地修改了,我们这里的b"hello"占五个字节,下一个正好是索引为5的地方,然后把索引为5到11的部分换成对应的字符。但是需要注意的是,一定要小心\0,我们知道C语言中一旦遇到了\0就表示这个字符数组结束了。

from ctypes import *

lib = CDLL("./mmp.dll")

# 这里把"hello"换成"hell",看看会发生什么

s = create_string_buffer(b"hell", 20)

lib.test(s) # s = hell

# 我们看到这里只打印了"hell",这是为什么?

# 我们看一下这个s

print(s.raw) # b'hell\x00 satori\x00\x00\x00\x00\x00\x00\x00\x00'

# 我们看到这个create_string_buffer返回的对象是可变的,在将s传进去之后被修改了

# 如果没有传递的话,我们知道它是长这样的。

"""

b'hell\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

hell的后面全部是C语言中的\0

修改之后变成了这样

b'hell\x00 satori\x00\x00\x00\x00\x00\x00\x00\x00'

我们看到确实是把索引为5到11(包含11)的部分变成了"satori"

但是我们知道C语言中扫描字符数组的时候一旦遇到了\0,就表示结束了,而hell后面就是\0,

因为即便后面还有内容也不会输出了,所以直接就只打印了hell

"""

另外除了create_string_buffer之外,还有一个create_unicode_buffer,针对于wchar_t,用法和create_string_buffer一样。

C语言中查看字符数组的长度

C语言中如何查看字符数组的长度呢?有两种方法,一种是通过sizeof,一种是通过strlen。话说我说这个干什么?算了,不管了。

#include

#include

int main() {

char s[] = "hello world";

//C语言中查看字符串的长度可以使用strlen,这个需要导入string.h头文件。strlen计算的就是字符的个数,不包括\0

//使用sizeof计算的结果是包含\0的,所以会比strlen计算的结果多1

printf("%d %d\n", strlen(s), sizeof(s) / sizeof(s[0])); // 11 12

return 0;

}

但是我们发现字符数组的创建方式是通过char s[]这种形式,如果是char *s呢?

#include

#include

int main() {

char *s = "hello world";

printf("%d %d\n", strlen(s), sizeof(s) / sizeof(s[0])); // 11 8

return 0;

}

我们看到使用strlen计算的结果是一样的,但是使用sizeof得到的结果却是不一样的。因为char *s,这个s我们虽然可以使用它来打印字符数组,但它本质上是一个指针,一个指针在64位机器上占8个字节,所以结果是8。而char s[]中的s虽然也指向字符数组的首地址,但它本质上是一个数组名,我们使用sizeof查看得到的结果还是字符数组中所有元素的总大小。

艾玛,你扯到C上面干啥。。。。。。你又不会C。。。。。。

66931f25e41327194f45bfbd9d113fd9.png

来源:https://www.cnblogs.com/traditional/p/12238984.html

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

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

相关文章

android自定义进度条百分比跟着走,Android自定义View实现水平带数字百分比进度条...

这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下:思路如下:第一部分是左侧的蓝色直线,代表已经完成的进度;第二部分是…

android动画view上移,在Android开发中使用View制作一个引导动画

在Android开发中使用View制作一个引导动画发布时间:2020-11-20 16:46:16来源:亿速云阅读:98作者:Leah这篇文章将为大家详细讲解有关在Android开发中使用View制作一个引导动画,文章内容质量较高,因此小编分享…

vivo android p 机型,vivo X21成全球首批Android P适配机型!vivo :不小心就秀实力了

原标题:vivo X21成全球首批Android P适配机型!vivo :不小心就秀实力了近日,2018谷歌I/O大会正式召开,会上发布了大家期待已久的Android P开发者预览版,给我们展示了众多全新特性,其中AI功能的进化让人十分眼…

直接修改html文本页面没变化,VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法分析...

本文实例讲述了VUE 直接通过JS 修改html对象的值导致没有更新到数据中解决方法。分享给大家供大家参考,具体如下:业务场景我们在使用vue 编写 代码时,我们有一个 多行文本框控件,希望在页面点击一个按钮 在 文本框焦点位置插入一个…

live2d内嵌html,博客(网页)添加 Live2D 看板娘

Live2D demoLive2D 看板娘插件 (https://www.fghrsh.net/post/123.html) 的前端 HTML 源码基于 API 加载模型,支持 定制 提示语增加 参数设置 一键定制看板娘,易用性增加 看板娘样式设置,可直接设置宽高度等支持多种一言接口,基于…

计算机启动进入不了桌面图标,电脑开机后不显示桌面图标如何通过修改注册表解决问题...

‍近来有用户发现电脑开机后不显示桌面图标,一般遇到这样的问题,我们会进入任务管理器结束explorer.exe资源管理器进程,再重新启动来解决这个问题。但是,如果这样还无法解决不显示电脑系统桌面图标的问题,那么可以按下…

药学专业报计算机一级有用吗,全网友泣泪劝阻!高考结束之后,什么专业千万不能报?...

原标题:全网友泣泪劝阻!高考结束之后,什么专业千万不能报?本文来源:魔都囡啊呀呀呀,高考终于结束啦,大家可以轻松下啦?不过高考的硝烟还没消散,接下来的一个问题就是非常…

如何去掉html body里的 nbsp,html的空格和nbsp怎么去除?

同楼主,这个问题我也碰到了。用html_parser好像不也行replace也不解决不完全,我希望把所有数据(房间类型,面积,位置,详细位置,发布时间,价格)放一行最后没办法只能这样了import requests ##导入…

计算机数据库管理基本知识,2015年计算机四级考试《数据库技术》基础知识:概念篇...

2015年计算机四级考试《数据库技术》基础知识:概念篇信息与数据1、 信息、物质、能量是组成客观世界并促进社会发展的三大基本要素;2、 信息(Information)--是客观世界事物的存在方式和运动状态的反映,是对事物之间相互联系、相互作用的描述。信息具有可…

coffeescript html5,HTML5——前端预处理技术(Less、Sass、CoffeeScript)

一、Less1.1、概要Less是一种动态样式语言,Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展。Less 将 CSS 赋予了动态语言的特性,如 变量, 继承&#…

计算机桌面程序名,深度技术win7旗舰版电脑桌面图标只显示名称了怎么办

就算是咱们没有刻意的在桌面创建程序的快捷打开方式,咱们windows系统预装的时候,也会在桌面自行的安装一些快捷方式,例如咱们比较熟悉的回收站、计算机、网络、IE图标等等,而这些图标的显示方式也是系统默认的,由图标和…

《计算机基础知识》读后感300字,计算机应用基础读后感

010在线为您甄选多篇描写计算机应用基础读后感,计算机应用基础读后感精选,计算机应用基础读后感大全,有议论,叙事 ,想象等形式。文章字数有400字、600字、800字....缓存时间: 2021-06-21计算机应用基础说课稿随着计算机应用的普及…

一调计算机专业综合理论试卷,一调计算机专业综合理论试卷(盐城)(新编)

一调计算机专业综合理论试卷(盐城)(新编) (15页)本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!14.9 积分盐城市2013年普通高校单独招生第一次调研考试计算机应用专业综合理论试卷第I卷(共…

计算机网络聚合怎么设置,交换机的端口聚合如何配置

交换机的端口聚合配置又是怎么回事呢,那么交换机的端口聚合如何配置的呢?下面是学习啦小编收集整理的交换机的端口聚合如何配置,希望对大家有帮助~~交换机的端口聚合配置的方法工具/原料计算机网络工具软件方法/步骤配置交换机Switch0:Switch>enSwit…

中学计算机教育特点,中学信息技术考点:信息的概念和基本特征

信息作为日常生活中最常见的词汇之一,与人类的生活息息相关。人们通过获得、识别自然界和社会的不同信息来区别不同事物,得以认识和改造世界。那么到底什么是信息呢?它的基本特征又有哪些?作为中学信息技术考点之一,福…

注意力测试软件系统,儿童注意力训练评估软件 - 训练评估软件 - 唯普诺心理,心理测评系统,心理测评软件,婴幼儿智能发育,心理软件...

注意力是儿童普遍存在的问题,他们在听课、看书、做作业、活动等事情上,往往不能集中注意力,既没有耐性也没有毅力,这和他们的先天有关,也和他们后天的养育、饮食、睡眠、环境等有关。解决儿童的注意力问题需要综合应用…

软件测试msf模型,Visual Studio 2010 Ultimate中MSF过程模型的设计

Visual Studio 2010 Ultimate中MSF过程模型的设计发表于:2010-04-06来源:作者:点击数:过程模型是 软件工程 学中的一部分,就好比我们用什么过程方法进行软件“房子”的建设。在本节中,我们将对VS 2010新提供…

手机屏幕什么计算机,windows 7系统中要实现智能手机无线投屏到计算机屏幕上可以借助的软件有哪些?...

Win7应用程序如果你实在要的话,自己上网去搜个无线投屏有一大堆。如何通过无线把电脑的屏幕投屏到电视?1、将电脑,电视连入相抄同网络。2、将电视打开,在“发现”页面点击上键,按右键选择袭“爱投屏”2113-“镜像”-“…

soul群聊显示服务器异常,soul群聊状态是什么

soul是一个非常好用的灵魂社交软件,很多用户都会注册这个平台的账号,然后使用手机进行使用,软件的社交方式非常的特别,主要是使用语音进行社交,保证是真人社交,但是不会有其他的信息出现,所以都…

php 验证ajax提交表单提交表单提交,使用AJAX表单提交将表单数据传递给PHP而不刷新页面...

芜湖不芜$(function () {$(form).bind(click, function (event) {event.preventDefault();// using this page stop being refreshing $.ajax({type: POST,url: post.php,data: $(form).serialize(),success: function () {alert(form was submitted);}});});});PHP<?phpif…