类型转换与字符串赋值、分割、合并、复制、比较、查询、翻转详解 (完整代码)

来源:互联网 发布:无锡软件开发 编辑:程序博客网 时间:2024/06/07 19:26

一、类型转换

char数组转int, long long, double:

#include<cstring>#include<cstdio>#include<cctype>#include<cstdlib>char str[100];int main(void){gets(str);if (!strchr(str, '.')){if (strlen(str) < 10)printf("%d\n", atoi(str)); // 转intelseprintf("%lld\n", atoll(str)); // 转long long,或者用strtoll(str, NULL, 10)}elseprintf("%.4f\n", atof(str)); // 转double并保留4位小数return 0;}

int, long long, double转char数组:

#include<cstring>#include<cstdio>#include<cctype>#include<cstdlib>#include<cmath>char str[100];int main(void){int num = 666;__int64 num2 = (__int64)1 << 55;double num3 = acos(-1.0);sprintf(str, "%d", num);puts(str);sprintf(str, "%lld", num2);puts(str);sprintf(str, "%.16f", num3); // 16位有效数字puts(str);return 0;}

PS:模10除10的方法更快

PS2:进制转换见这篇文章。


二、字符串赋值

PS:我们不讨论scanf()和gets()这种从键盘输入的方法。

#include<cstdio>#include<cstring>char str[20];int main(void){char *p = str;///尝试Ap = "Minecraft";//不可取的做法/*双引号做了3件事:1. 申请了空间,存放了字符串2. 在字符串尾加上了'\0'3. 返回地址,准确地说是指针常量*/printf("%s %p\n\n", p, p);//output:Minecraft 00403024///尝试B//*p = "Minecraft";/*照样不行,因为右边返回的是一个指针常量这和str = "Minecraft";是一样的*////尝试Cp = "Minecraft";strcpy(str, p);puts(str);//成功,详见下方解释///尝试Dp = "Minecraft";sprintf(str, "%s", p);puts(str);//成功return 0;}

先看看strcpy()的实现代码:

char *strcpy(char *strDest, const char *strSrc){char *strDestCopy = strDest;if ((strDest == NULL) || (strSrc == NULL))//两边指针都为空throw "Invalid argument(s)";while (*strDest++ = *strSrc++);//先赋值,在递增,最后判断返回值是否为空指针(NULL)return strDestCopy;}
这相当于把char数组一个一个地赋给str。


三、字符串分割、合并、复制、比较、查询、翻转及自定义字符串函数

先放上C风格的代码:

/*请务必运行本程序以便对照阅读*/#include<cstring>#include<cstdio>#include<cctype>#include<cstdlib>///没有换行的puts()函数void puts1(const char *str){while (*str) //*str != '\0'putchar(*str++);}///前后换行的puts()函数void puts2(const char *str){putchar('\n');while (*str) //*str != '\0'putchar(*str++);putchar('\n');}///连换两行的puts()函数void puts3(const char *str){while (*str) //*str != '\0'putchar(*str++);putchar('\n');putchar('\n');}int main(void){///1. 分割与复制char str[] = "num = 666", str2[20], str3[20], key[20];int val;strcpy(str2, strtok(str, " ="));puts(str2);val = atoi(strtok(NULL, " ="));///分割一个元组后,要继续分割后面的元组,请将参数改为NULL///2. 比较与合并printf("%d\n\n请输入两个字符串:\n", val);memset(str2, 0, sizeof(str2));scanf("%s%s", str2, str3);getchar();puts3(strcmp(str2, str3) < 0 ? strcat(str2, str3) : strcat(str3, str2));///3.1 查询const char NAME[] = "Takanashi Rikka";puts(strchr(NAME, 'k') ? "YES" : "NO");puts(strchr(NAME, 'b') ? "YES" : "NO");puts3(strstr(NAME, "Rikka") ? "YES" : "NO");///3.2 替换strcpy(str2, "he put his book on the table.");strcpy(key, "book");char *p = strstr(str2, key), *p2 = key;for (int i = 0; i < strlen(key); ++i) key[i] = toupper(key[i]);while (*p2) *p++ = *p2++;puts(str2);///4.1 翻转strcpy(str2, "eca");///请勿翻转中文字符puts(strrev(str2));///4.2 检查一个字符串是否为回文字符串strcpy(str2, "TAT");strcpy(str3, str2);puts(strcmp(str2, strrev(str3)) ? "NO" : "YES");///注意strrev会修改传入的字符串///5. 当读到一个空行就结束,否则输出char ch;while (true){ch = getchar();if (ch == '\n')break;ungetc(ch, stdin); ///放回到标准输入流(键盘)memset(str2, 0, sizeof(str2));gets(str2);puts(str2);getchar();}return 0;}

C++STL:

#include<cstdio>#include<iostream>#include<string>using namespace std;string str, str2, str3;int main(void){///1. 条件读入///PS: 在处理前后空格时,依旧没scanf("%s",str);强大puts("请输入一行含有若干'#'的话:");while (getline(cin, str, '#')){if (str == "") continue;///遇到连续的'#'if (~str.find("\n", 0))str.erase(str.size() - 1);///去掉输入最后的换行(不写的话会多出一个换行)cout << str << endl;}cout << endl;///2. 比较与合并str = "ace", str2 = "ab";cout << (str < str2 ? str + str2 : str2 + str) << endl;cout << endl;///3. 查询str = "Takanashi Rikka";puts(~str.find("a", 0) ? "YES" : "NO");puts(~str.find("S", 0) ? "YES" : "NO");///未找到就返回-1(string::npos)cout << endl;///4. 插入str.insert(3, "OOOO");cout << str << endl;cout << endl;///5. 片段截取与删除str2 = ("Now is the time to get AC.");str3.assign(str2, 11, 4);///4指要截取的长度//等价的做法:str3 = str2.substr(11, 4);cout << str3 << endl;str2.erase(3, 6);cout << str2 << endl;cout << endl;return 0;}


四、补充

Q:使用ungetc()如果把读出的数据放回到缓冲区去后,没有将缓冲区的数据读出来,就再次试图把读出的数据放回到缓冲区,会发生什么?

A:数据是放不进去的。我们可以把缓冲区看做一个可变化的容器,当你把试图用ungetc()函数把读出的数据放回到缓冲区,缓冲区这个容器就为这些数据分配相应的大小空间,之后这个空间是不变的,直到你把缓冲区的数据读出去,所以你在没有释放缓冲区时,再次想往缓冲区装数据是装不进去的。


****转载请注明出处:http://blog.csdn.net/synapse7/article/details/10282199****

原创粉丝点击