C/C++/QT中的字符串

44 篇文章 10 订阅

C语言中的字符串

C语言不存在字符串数据类型,其通过一个以’\0’结尾的字符数组实现;所有字符串都是以\0结尾的,所有以\0结尾的字符数组都可以看作字符串。
字符数组的定义,常见有如下几种形式:
char a[10] ={‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’};
在这里插入图片描述
char a[10] ={‘a’,‘b’,‘c’,‘d’,‘e’};
在这里插入图片描述
char c[ ] ={‘C’,‘h’,‘i’,‘n’,‘a’};
在这里插入图片描述
char c[ ] =“China”;
在这里插入图片描述
举例:

char c[5] = "China";  //非法赋值,后面的字符串是6个字符
char c[6] = "China";  //合法,这种赋值方式只能在数组定义并初始化的时候
//不能用赋值语句将一个常量字符串或字符数组赋值给另一个字符数组
str1[ ] = "China"; //非法,只有在字符串定义时合法
str2 = "China"; //非法
str3 = str2; //非法
//字符数组的输出
char str1[ ] = "C++language";
cout<<"String1:"<<str1<<endl;

关于字符数组的几点说明:
1、定义char a[5],则说明,a是个字符数组,在内存中占五个字节空间;如果用a来存储字符串,则最多只能有4个有效字符,必须给\0留个空间;
2、a按字符串来算长度是从a这个地址开始,计数到\0字符,这之间的字符个数是字符串a的长度;一般常用strlen()函数来获取字符串长度;
3、计算a的大小用sizeof命令,sizeof(a)得到的是a在内存中占的字节数;
4、字符串与字符数组不能混为一谈。它们相同在形式上,区别就在,字符串一定有\0结束符,而数组不需要!什么是字符串?就是以双引号引起来的数据才叫字符串。字符数组可以存储字符串;
5、C语言汇总不存在字符串数据类型,其通过一个以’\0’结尾的字符数组实现;;在C++编程中建议使用string替换C字符串;
6、char p = “abc”;是在文字常量区分配了一块内存放"abc",然后在栈上分配一地址给p并指向这块地址;
7、char
p是一个指针,根本没分配内存,他指向的"abc123ABC" 是只读的,不能改变

数组:
数组名代表数组元素的地址;
数组名相当于指向数组第一个元素的指针,即a与&a[0]等价;
数组名a是地址常量,不是变量,不能给a赋值;
a[i]等价于*(pointer+i),等价于pointer[i]

&a是指向数组的指针;&a+1将跨越16个字节;&a相当于管辖范围上升了一级;
a是数组的第一个元素a[0];即a等价于a[0];*a相当于管辖范围下降了一级;

数组三条规律
数组名相当于指向数组第一个元素的指针;
&E相当于把E的管辖范围上升了一个级别;
*E相当于把E的管辖范围下降了一个级别;

C++语言中的字符串

在C++中有两种字符串的概念:
1、string类:
由于string为类,定义时实际上是定义了一个对象,而初始化方式也就决定了调用何种构造函数来进行构造
string a;//定义一个空字符串。 string b=“test string”;//定义一个字符串并初始化为test string。
关于string类的详细使用说明,在其他博文介绍。
2、字符数组:
C++继承了C语言的概念,而在C语言中字符串指的是字符数组,并约定以\0作为结束符
char a[20] = “test string”; //定义一个字符串并初始化为test string;;char *b = “test string”; //与a类似,但这个是直接使用常量字符串的地址,所以字符串b是只读的。

Qt中的字符串

Qt中除了可以使用C/C++中的字符串,还封装了QString类用于操作字符串。
Qt使用printf打印无输出问题
尝试在QT中使用printf打印结果不实时输出,是因为打印结果在缓冲区未被释放,所以无法显示,解决方法:
printf在glibc中默认为行缓冲,遇到以下几种情况会刷新缓冲区,输出内容:
(1)缓冲区填满;
(2)写入的字符中有换行符\n或回车符\r;
(3)调用fflush手动刷新缓冲区;//fflush(stdout);//释放缓冲区
(4)调用scanf要从输入缓冲区中读取数据时,也会将输出缓冲区内的数据刷新。
可使用setbuf(stdout,NULL)关闭行缓冲,或者setbuf(stdout,uBuff)设置新的缓冲区,uBuff为自己指定的缓冲区。也可以使用setvbuf(stdout,NULL,_IOFBF,0);
来改变标准输出为全缓冲。全缓冲与行缓冲的区别在于遇到换行符不刷新缓冲区。

常见字符串转换
[QString转char[]数组]

char name[10];
char* ptr;
QString str = ui->namelineEdit->text();
ptr = str.toLatin1().data();
memcpy(p->name,ptr,10); //就是这一句,必须加,不然只是把指针指向了值,并没有赋值

[char[]数组转QString]

char c[]="12ff";
QString str=QString(QLatin1String(c));

[QString 转换为 char*]

//方法1:
QString  str;
char*  ch;
QByteArray ba = str.toLatin1(); // must
ch=ba.data();
//方法2:
QString  filename;
std::string str = filename.toStdString();
const char* ch = str.c_str();

[char *转为QString]

char *ch="hello!";
QString str(ch);   // Qt5     
QString str = QString::fromUtf8(ch);    //  Qt4

[unsigned char* 转QString]

unsigned char* ch;
std::string str = (char*)ch;
QString sstr = QString::fromStdString(str);

[char[]数组之间赋值]

char *strcpy(char *dst, const char *src);//把 src 所指向的字符串复制到 dest,返回指向最终的目标字符串 dest 的指针
char a[7] = "abcdef";
char b[4] = "ABC";
strcpy(a,b);
printf("%c",a[5]);//输出f
printf("%c",a);//输出ABC\0ef,strcpy碰到\0确实会停止复制,但a中未被覆盖的字符会被保留

[unsigned char转char]

unsigned char szBuf[512] 
reinterpret_cast<char*>(szBuf)

[QString转string]

QString.toStdString();

[string转QString]

QString::fromStdString(string);

C语言str系列库函数

strcmp
strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数
函数原型:extern int strcmp(const char *s1,const char *s2);//s1=s2,则返回零;s1<s2,则返回负数;s1>s2,则返回正数。

    char cA[6] = "hello";
    char *cB = "hello";
    int ret = strcmp(cA,cB);//ret=0

strcpy
strcpy,即string copy(字符串复制)的缩写,原型声明:char strcpy(char dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串,返回指向dest的指针。

    char printInfo[50];
    memset(printInfo, 0x00, 50);
    strcpy(printInfo, "CB532测试打印信息");

[strncpy]
strncpy函数用于将指定长度的字符串复制到字符数组中,函数原型:
char *strncpy(char *dest, const char *src, int n);//表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。

    char src[] = "It's Monday and it's raining";
    char dest[40];
    strncpy(dest,src,10);//dest打印It's Monda?u?(后面乱码)
    strncpy(dest,src,strlen(src)+10);//dest打印It's Monday and it's raining

memcpy
void *memcpy(void *dest, const void *src, size_t n);//用来将src地址处的内容拷贝n个字节的数据至目标地址dest指向的内存中去,函数返回指向dest的指针

    char   *s= "Golden Global View";
    char   d[20];
    memcpy(d,s,strlen(s));//d打印Golden Global View

[memset]
void *memset(void *s,int c,size_t n) //将已开辟内存空间 s 的首 n 个字节的值设为值 c(给空间初始化),返回s
//memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)

    char szVerBuf0[512+1];
    memset(szVerBuf0,0x00,sizeof(szVerBuf0));

strlen
extern unsigned int strlen(char *s);
strlen所作的是一个计数器的工作,它从内存的某个位置开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’)。

    char aa[200]="Hello,World!";
    printf("strlen(aa)=%d.\n",strlen(aa));//打印12
    printf("sizeof(aa)=%d.\n",sizeof(aa));//打印200

[strstr]
char *strstr(const char *haystack, const char *needle);//在字符串 haystack 中查找第一次出现字符串 needle 的位置并返回,不包含终止符 ‘\0’,如果未找到则返回 null。

    char haystack[20] = "RUNOOB2";
    char needle[10] = "NOOB";
    char *ret;
    ret = strstr(haystack, needle);
    printf("substr:%s\n", ret);//打印substr:NOOB2

strcspn
size_t strspn(const char *s, const char * accept);//若strcspn()返回的数值为n, 则代表字符串s 连续有n 个字符都包含accept 内的字符

char *s="Golden Global View";
    cout<<strspn(s, " ")<<endl;//0,开始不包含空格
    cout<<strspn(s, "loG")<<endl;//3
    cout<<strspn(s, "nedloG")<<endl;//6
    cout<<strspn(s, "nGew")<<endl;//1

strcat
char *strcat(char *dest, const char *src);//把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

   char src[50], dest[50];
   strcpy(src,  "This is source");
   strcpy(dest, "This is destination");
   strcat(dest, src);
   printf("最终的目标字符串: |%s|", dest);//最终的目标字符串: |This is destinationThis is source|

substr
basic_string substr(size_type _Off = 0,size_type _Count = npos) const;
//_Off:所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0。
//_Count:复制的字符数目
//返回值:一个子字符串,从其指定的位置开始

memcmp
int memcmp(const void *str1, const void *str2, size_t n)) 把存储区 str1 和存储区 str2 的前 n 个字节进行比较
str1 – 指向内存块的指针。
str2 – 指向内存块的指针。
n – 要被比较的字节数
返回值
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str1 大于 str2。
如果返回值 = 0,则表示 str1 等于 str2。

memchr
void *memchr(const void *str, int c, size_t n) 在参数 str 所指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。
参数
str – 指向要执行搜索的内存块。
c – 以 int 形式传递的值,但是函数在每次字节搜索时是使用该值的无符号字符形式。
n – 要被分析的字节数。
返回值
该函数返回一个指向匹配字节的指针,如果在给定的内存区域未出现字符,则返回 NULL。

printf
printf()是C语言标准库函数,用于将格式化后的字符串输出到标准输出。标准输出,即标准输出文件,对应终端的屏幕。printf()申明于头文件stdio.h
int printf ( const char * format, … );//函数原型
返回值:
正确返回输出的字符总数,错误返回负值,与此同时,输入输出流错误标志将被置值,可由指示器ferror来检查输入输出流的错误标志。
printf的格式控制字符串组成如下:
%[flags][width][.prec][length]type
%[标志][最小宽度][.精度][类型长度]类型

fprintf
fprintf()用于文件操作,函数原型
#include <stdio.h>
int fprintf( FILE *stream, const char *format, … );
fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件.因此fprintf()可以使得信息输出到指定的文件
stdout – 标准输出设备
stderr – 标准错误输出设备
stdout和stderr区别:都是默认向屏幕输出,stdout是行缓存的,而stderr是无缓存的,直接输出。

//示例:输出HelloMary 到文件output.txt
char name[20] = "Mary";
FILE *out;
out = fopen( "output.txt", "w" );
if( out != NULL )
	fprintf( out, "Hello %s\n", name );
fclose(out);

sprintf
函数功能:把格式化的数据写入某个字符串
函数原型:int sprintf( char *buffer, const char *format [, argument] … );
返回值:字符串长度(strlen)

//示例
char name[20] = "make";
int age = 20;
char desc[50];
sprintf(desc,"my name is %s,age:%d.",name,age);
printf(":%s\n",desc);//输出:my name is make,age:20

snprintf
函数原型:int snprintf(char* dest_str,size_t size,const char* format,…);
将可变个参数(…)按照format格式化成字符串,然后将其复制到str中。
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(‘\0’);
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符(‘\0’),返回值为欲写入的字符串长度。

    const int LEN = 64;
    char buf[LEN] = {0};
    char buf2[LEN] = {0};
    int n = snprintf(buf, 5, "abcdefg");//返回值是欲写入的字符串长度,而不是实际写入的字符串度
    printf("n=%d,buf=%s\n", n, buf);//想要写入7个字符,但实际只写入了4个字符,尾部是\0

    int n2 = snprintf(buf2,LEN,"age:%d,name:%s",20,"chw");//正常用法
    printf("n2=%d,buf2=%s\n", n2, buf2);

打印

n=7,buf=abcd
n2=15,buf2=age:20,name:chw

vsnprintf

#include <stdio.h>
       int printf(const char *format, ...); //输出到标准输出
       int fprintf(FILE *stream, const char *format, ...); //输出到文件
       int sprintf(char *str, const char *format, ...); //输出到字符串str中
       int snprintf(char *str, size_t size, const char *format, ...); //按size大小输出到字符串str中

以下函数功能与上面的一一对应相同,只是在函数调用时,把上面的…对应的一个个变量用va_list调用所替代。在函数调用前ap要通过va_start()宏来动态获取。


#include <stdarg.h>
       int vprintf(const char *format, va_list ap);
       int vfprintf(FILE *stream, const char *format, va_list ap);
       int vsprintf(char *str, const char *format, va_list ap);
       int vsnprintf(char *str, size_t size, const char *format, va_list ap);

以vsnprintf举例:

int cs_snprintf(char *s, int size, const char *fmt, ...) //该自定义函数,与系统提供的snprintf()函数相同。
{
    va_list ap;
    int n=0;
    va_start(ap, fmt); //获得可变参数列表
    n=vsnprintf (s, size, fmt, ap); //写入字符串s
    va_end(ap); //释放资源
    return n; //返回写入的字符个数
}

    char str[1024];
    cs_snprintf( str, sizeof(str), "%d,%d,%d,%d",5,6,7,8);
    printf("%s\n",str);

打印

5,6,7,8

strdup
c语言中常用的一种字符串拷贝库函数,一般和 free() 函数成对出现
char *strdup(char *s);//将字符串拷贝到新建的位置处,strdup()在内部调用了malloc()为变量分配内存,不需要使用返回的字符串时,需要用free()释放相应的内存空间,否则会造成内存泄漏.
返回值:返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值。

strtok
char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
str – 要被分解成一组小字符串的字符串。
delim – 包含分隔符的 C 字符串。
示例

    char str[80] = "chu-123-xx";
    const char s[2] = "-";
    char *token;
    token = strtok(str, s);/* 获取第一个子字符串 */
    while( token != NULL ) {/* 继续获取其他的子字符串 */
        printf( "%s\n", token );
        token = strtok(NULL, s);
    }

打印
chu
123
xx

sizeof()、strlen()、length()和size()

sizeof():返回所占总空间的字节数
(1)、对于整型字符型数组
(2)、对于整型或字符型指针
sizeof(…)是运算符,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。

strlen():返回字符数组或字符串所占的字节数
(1)、针对字符数组
(2)、针对字符指针
strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个’\0’,如果你只定义没有给它赋初值,这个结果是不定的,它会从aa首地址一直找下去,直到遇到’\0’停止。

c/c++ strlen(str)和str.length()和str.size()都可以求字符串长度。
其中str.length()和str.size()是用于求string类对象的成员函数
strlen(str)是用于求字符数组的长度,其参数是char*。

举例:
1)char* ss = “0123456789”;
sizeof(ss)为4,ss是指向字符串常量的字符指针,sizeof 获得的是指针所占的空间,则为4
sizeof(*ss)为1,ss是第一个char字符,则为1
2)char ss[] = “0123456789”;
sizeof(ss)为11,ss是数组,计算到’\0’位置,因此是(10+1)
sizeof(ss)为1,ss是第一个字符
3)char ss[100] = “0123456789”;
sizeof(ss)为100,ss表示在内存中预分配的大小,100
1
strlen(ss)为10,它的内部实现用一个循环计算字符串的长度,直到’\0’为止。
4)int ss[100] = “0123456789”;
sizeof(ss)为400,ss表示在内存中预分配的大小,100
4
strlen(ss)错误,strlen参数只能是char
,且必须是以’\0’结尾
5)char[] a={‘a’,‘b’,‘c’};
sizeof(a)的值应该为3。
char[] b={“abc”};
sizeof(b)的值应该是4。
若string str={‘a’,‘b’,‘c’,‘\0’,‘X’};
那么sizeof(str)为5,strlen(str)为3。

string中length()和size()
c++中的size()和length()没有区别
这两个函数一样。 length()是因为沿用C语言的习惯而保留下来的,string类最初只有length(),引入STL之后,为了兼容又加入了size(),它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。
string类的size()/length()方法返回的是字节数,不管是否有汉字
汉字一般占用2个字节,数字和英文字母占用1个字节
特殊字符一般英文输入法是占用1个字节,中文输入法占用2个或4个字节,比如英文感叹号占用1个字节,中文输入的感叹号占用2个字节

字符串中含有\r\n,打印时不换行问题

待打印的字符串包含\r\n,打印输出\r\n,所有字符都打印在一行,没有换行,阅读起来很不方便,可做如下处理再打印

    std::string input = "v=0\\r\\no=MetaRtc 140729008552664 2 IN IP4 0.0.0.0\\r\\ns=MetaRtcSession\\r\\nt=0\\r\\n";
    std::string::size_type pos = 0;
    while ((pos = input.find("\\r\\n", pos)) != std::string::npos)
    {
        input.replace(pos, 4, "\r\n");
    }
    printf("localsdp=%s\n",input.c_str());

打印输出

srtp init success!
localsdp=v=0
o=MetaRtc 140729008552664 2 IN IP4 0.0.0.0
s=MetaRtcSession
t=0 0
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt,可以使用QString类的toInt()函数将字符串转换为数字。这个函数接受一个可选的基数参数,用于指定字符串的进制。默认情况下,基数为10,表示十进制。如果需要将字符串转换为其他进制的数字,可以使用QString类的setNum()函数将数字转换为字符串,并指定所需的进制。例如,要将十进制字符串转换为十六进制字符串,可以使用setNum()函数的第二个参数将基数设置为16。然后,可以使用toUpper()函数将结果转换为大写,并使用setText()函数将结果设置为控件的文本。下面是一个示例代码片段,演示了如何在Qt实现字符串转数字的功能: ```cpp void Widget::on_btnDec_clicked() { QString str = ui->editDec->text(); int val = str.toInt(); // 将字符串转换为十进制数字 str = QString::number(val, 16); // 将数字转换为十六进制字符串 str = str.toUpper(); // 将结果转换为大写 ui->editHex->setText(str); // 设置十六进制字符串到相应的控件 str = QString::number(val, 2); // 将数字转换为二进制字符串 ui->editBin->setText(str); // 设置二进制字符串到相应的控件 } ``` 注意,以上代码是一个槽函数,当按钮被点击时执行。在代码,editDec是一个QLineEdit控件,用于输入十进制数。editHex和editBin分别是用于显示转换结果的QLineEdit控件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [初识QT(二十六)——Qt字符串与数字之间的转换方法详解](https://blog.csdn.net/qq_35789421/article/details/99436843)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值