3.C/C++字符串

1.不使用庫函數將整數轉換爲字符串

C語言提供了將幾個標準庫函數,可以將任意類型的(整形、浮點型、長整形)的數字轉換爲字符串

itoa():將整形值轉換爲字符串 
ltoa();將長整形轉換爲字符串 
ultoa();將無符號長整形轉換爲字符串 
gcvt();將浮點數轉換爲字符串,取四捨五入 
ecvt();將雙精度浮點數轉換爲字符串,轉換結果中不包含十進制小數點 
fcvt();將指定位數轉換精度 
還可以使用sprintf系類函數把數字轉換爲字符串,這種方式比itoa系列函數速度慢

#include<stdio.h>
#include<iostream>
using namespace std;

void int2str(int n, char*str)
{
	char buf[10] = {0};  //臨時數組
	int i = 0;    //臨時數組buf的下標
	int j = 0;   //str的下標
	int len=0;

	int temp = n < 0 ? -n : n; //取數字n的絕對值

	if (n < 0)  //首先對負數做處理
	{
		str[j] = '-';
		j++;
	}
	
	//將數字倒序放在臨時數組
	while (temp)
	{
		buf[i] = temp%10 + '0';
		i++;
		temp /= 10;
	}

	//轉換
	len = i - 1;
	while (len>=0)
	{
		str[j] = buf[len];
		j++;
		len--;
	}
	str[j] = '\0';
}

int main()
{
	int num;
	char p[10];
	cout << "please input the number:" << endl;
	cin >> num;

	int2str(num, p);
	cout << "ouput: " << p << endl;
	return 0;
}
please input the number:

-1234
ouput: -1234


2.不使用庫函數將字符串轉換爲數字

與數字轉換爲字符串類似,C/C++提供了幾個標準的庫函數,可以將字符串轉換爲任意類型(整型,長整型,浮點型)的數字。下面列舉其函數

atof();將字符串轉換爲雙精度浮點型值 
atoi();將字符串轉換爲整型值 
atol();將字符串轉換爲長整型 
strtod();將字符串轉換爲雙精度浮點型值,並報告不能被轉換的所有剩下數字 
strtol();將字符串轉換爲長整型值,並報告不能被轉換的所有剩下的數字 
strtoul();將字符串轉換爲無符號長整型,並報告不能被轉換的所有剩下的數字

//2.不使用庫函數將數字符串轉換爲數字
#include<iostream>
using namespace std;

int str2int(const char * str)
{
	int temp=0;
	const char *ptr = str;  //ptr保存str字符串開頭
	if (*str == '-' || *str == '+') //如果第一個字符是正負號,則移到下一個字符
	{
		str++;
	}
	while (*str != 0)
	{
		if ((*str < '0') || *str > '9')  //如果當前字符不是數字,則退出循環
		{
			break;
		}
		temp = temp * 10 + (*str - '0');  //如果當前字符是數字,則計算數值,然後移到下一個字符
		str++;
	}
	if(*ptr=='-')  //如果字符串以‘-’開頭,則轉換成其相反數
	{
		temp = -temp;
	}
	return temp;
}
int main()
{
	int n = 0;
	char p[10] = "";
	cout << "input: " << endl;
	//cin >> p[10];
	cin.getline(p, 20);
	n = str2int(p);
	cout << "output:" << n << endl;
	return 0;
}


input:
-1234
output:-1234



3.編程實現strcpy函數

//3.編程實現strcpy函數
#include<stdio.h>
char * strcpy(char * strDest, const char * strSrc)
{
	if ((strDest == NULL) || (strSrc == NULL))
	{
		return NULL;
	}
	char *strDestCopy = strDest; //保存目標字符串的首地址
	int i = 0;
	//for (i = 0; strSrc[i] != '\0'; strDest[i] = strSrc[i], i++)
	while (strSrc[i]!='\0')
	{
		strDest[i] = strSrc[i]; //把strSrc字符串的內容複製到strDest中
		i++;
	}
		strDest[i] = '\0'; //加入結束符
	return strDestCopy;  //返回首地址
}

int main()
{
	char strSrc[] = "hello world";
	char strDest[20];
	strcpy(strDest, strSrc);
	printf("strDest:%s\n", strDest);
	return 0;
}

strDest:hello world



4.編程實現計算字符串的長度

//4.編程實現計算字符串的長度
#include<stdio.h>

int strlen1(const char* src)
{
	if (src == NULL)   //判斷src是否有效
	{
		return 0;
	}
	int len = 0;
	while (*src!='\0')
	{
		*src++;
		len++;
	}
	return len;
}

int strlen2(const char* src)
{
	if (src == NULL)  //判斷src是否有效
	{
		return 0;
	}
	const char *temp = src;  //保存src的首地址
	while (*src!='\0')
	{
		src++;
	}
	
	return (src - temp); //返回指針差
}

int main()
{
	char p[] = "Hello World!";

	printf("Strlen1 len: %d\n", strlen1(p));
	printf("Strlen2 len: %d\n", strlen2(p));
	return 0;
} 
//第二種方法效率更好

Strlen1 len: 12
Strlen2 len: 12




5.編程實現字符串中子串的查找

編寫一個函數,實現strstr,即從一個字符串中,查找另一個字符串的位置,如果輸入strstr("12345","34")返回值爲2,即在2號位置找到字符串34.

#include<stdio.h>
int strstr(const char* src, const char* sub)
{
	const char *bp = src; //定義指針bp指向src首地址
	const char *sp = sub;
	int flag = 0;
	const char *temp = src; //定義一個臨時指針temp,暫時先指向src首地址
	if (src == NULL || sub == NULL)  //判斷src和sub是否有效
	{
		return 0;
	}
	while (*src)  //遍歷src
	{
		sub = sp;
		while (*src == *sub) //如果src與sub字符相等進入,如果不等,src++
		{
			src++;  //然後src和sbu都加1,比較下一個字符是否相等
			sub++;
			flag = 1;
			if (*sub == '\0')  //如果sub結束了,那就是找到了子串
			{
				return (temp - bp);  //輸出子串的位置,bp是首地址,temp存儲的是第一個相等字符的前一個
				break;                   //字符的位置,然後與首地址相減再加1,就得到最終結果
			}
		}
		if (flag == 1) //flag的作用是如果在上一個while循環中src執行了+1,這裏就不需要再執行一次了
		{              //所有先對src--,然後在src++
			src--;
			flag = 0;
		}
		src++;  //src加1,比較下一個字符
		temp = src;
		if (*src == '\0') //如果src下一個字符是空,那就結束,
		{
			return 0;
		}
	}
}

int main()
{
	char p[] = "123345";
	char q[] = "34";
	printf("the position of sub is : %d\n", strstr(p, q));
	return 0;
}
the position of sub is : 3



6.編程判斷字符串是否是迴文,例如“level”是迴文

//6.編程判斷字符串是否是迴文
//例如“level”是迴文

#include<iostream>
using namespace std;

int IsRevStr(char * str)
{
	int i, len;
	int found = 1;  //1表示是迴文,0表示不是迴文
	if (str == NULL)
	{
		return -1;
	}
	len = strlen(str);
	for (i = 0; i < len / 2; i++)
	{
		if (str[i] != str[len - i - 1])  //不是迴文
		{
			found = 0;  
			break;
		}
	}
	return found;
}
int main()
{
	char str1[] = "1234321";
	char str2[] = "1234221";

	int test1 = IsRevStr(str1);
	int test2 = IsRevStr(str2);

	cout << "str1 is " << (test1 == 1 ? "" : "not ") << "reverse string." << endl;
	cout << "str2 is " << (test2 == 1 ? "" : "not ") << "reverse string." << endl;

	return 0;
}

str1 is reverse string.
str2 is not reverse string.




7.編程實現stcmp庫函數
對於兩個字符串str1,str2,若相等,則返回0,若str1大於str2,則返回1,若str1小於str2,則返回-1

//7.編程實現stcmp庫函數
//對於兩個字符串str1,str2,若相等,則返回0,若str1大於str2,則返回1,若str1小於str2,則返回-1
#include<iostream>
using namespace std;

int mystrcmp(const char*src, const char* dst)
{
	int ret = 0;
	while (!(ret=*(unsigned char *)src-*(unsigned char *)dst) && *dst)
	{
		src++;  //循環比較兩個字符串是否相等,如果不等或者dst字符串到了末尾,退出循環,
		dst++;  //與後面的*dst和*src有一個在就可以,如果src到了結尾,而dst沒到結尾,則!ret=0,同樣會結束循環
	}
	if (ret < 0)
		ret = -1;
	else if (ret > 0)
		ret = 1;
	return ret;
}

int main()
{
	char str[10] = "1234567";
	char str1[10] = "1234567";
	char str2[10] = "12345678";
	char str3[10] = "1234566";

	int test1 = mystrcmp(str, str1);
	int test2 = mystrcmp(str, str2);
	int test3 = mystrcmp(str, str3);

	cout << "test1 = " << test1 << endl;
	cout << "test2 = " << test2 << endl;
	cout << "test3 = " << test3 << endl;

	return 0;
}

test1 = 0
test2 = -1
test3 = 1




8.編寫字符串反轉函數strrev

如:輸入“abcd”,輸出應爲“dcba”

//8.編寫字符串反轉函數strrev
#include<iostream>
using namespace std;
char* strrev1(char* str)  //遍歷字符串
{                         //第一個與最後一個交換,依次循環
	int len = strlen(str);
	char *tmp = new char[len + 1];

	strcpy_s(tmp,len+1,str);

	for (int i = 0; i < len / 2; i++)
	{
		char c = tmp[i];
		tmp[i] = tmp[len - i-1];
		tmp[len - i - 1] = c;
	}
	return tmp;
}
 
int main()
{
	char * str = "123456";
	cout << str << endl;

	char* str1 = strrev1(str);
	cout << "strrev1(str) = " << str1 << endl;
	return 0;
}

123456
strrev1(str) = 654321




9.編程實現任意長度的兩個正整數相加

//9.編程實現任意長度的兩個正整數相加
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

char * addBigInt(char * num1, char *num2)
{
	int c = 0;// 進位,開始最低進位爲0
	int i = strlen(num1)-1;   //指向第一個加數的最低位
	int j = strlen(num2)-1;   //指向第二個加數的最低位

	//得到兩個數中較大數的位數並加1,作爲結果的位數
	int maxLength = strlen(num1) >= strlen(num2) ? strlen(num1) + 1 : strlen(num2) + 1; 

	char *rst = (char*)malloc(maxLength + 1);  //保存結果
	int k;
	if (rst == NULL)
	{
		printf("malloc error\n");
		exit(1);
	}
    
	rst[maxLength] = '\0';  //字符串最後一位爲'\0';
	k = strlen(rst) - 1;   //指向結果數組的最低位

	while ((i>=0)&&(j>=0))
	{
		rst[k] = ((num1[i] - '0') + (num2[j] - '0') + c) % 10 + '0';
		c = ((num1[i] - '0') + (num2[j] - '0') + c) / 10;
		i--;
		j--;
		k--;
	}
	while (i>=0)
	{
		rst[k] = ((num1[i] - '0')+ c) % 10 + '0';
		c = ((num1[i] - '0')+ c) / 10;
		i--;
		k--;
	}
	while (j>=0)
	{
		rst[k] = ((num2[j] - '0') + c) % 10 + '0';
		c = ((num2[j] - '0') + c) / 10;
		j--;
		k--;
	}
	rst[0] = c +'0';
	if (rst[0] !='0')
	{
		return rst;
	}
	else
	{
		return rst + 1;   //如果最高位等於零,那麼就從結果str的第二個元素開始輸出
	}
}
int main()
{
	char num1[] = "123";
	char num2[] = "996";
	char *result = NULL;

	result = addBigInt(num1, num2);
	printf("%s + %s = %s\n", num1, num2, result);

	return 0;
}


123 + 996 = 1119




10.編程實現字符串的循環右移

編寫函數能把一個char組成的字符串循環右移n個,例如原來是“abcdefghi”,如果n=2,移位後應該是“hiabcdefg”

//10.編程實現字符串的循環右移
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void loopMove(char* str, int n)
{
	int i = 0;
	char *temp = NULL;
	int strLen = strlen(str);
	char *head = str;
	n = n%strLen;
	temp = (char*)malloc(n);

	for (i = 0; i < n; i++)
	{
		temp[i] = head[strLen - n + i];
	}
	for (i = strLen - 1; i >= n; i--)
	{
		head[i] = head[i - n];
	}
	for (i = 0; i < n; i++)
	{
		head[i] = temp[i];
	}
	free(temp);
}
int main()
{
	char string[] = "abcdefghi";
	int steps = 0;
	printf("string: %s\n", string);
	printf("input steps: ");
	scanf_s("%d", &steps);
	loopMove(string,steps);
	printf("after loopMove %d: %s\n", steps, string);
	return 0;
}
string: abcdefghi
input steps: 2
after loopMove 2: hiabcdefg



11.刪除制定長度的字符

例如:假設一個字符串“abcdefg”,如果要從第二個開始(索引爲1),刪除兩個字符,則刪除後的字符串是“adefg”

//11.刪除制定長度的字符
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char *deleteChars(char* str, int pos, int len)
{
	char *p = str + pos - 1;//指向pos位置字符
	int tt = strlen(str);   //計算字符長度
	
	if ((pos < 1) || (p - str) > tt) //檢查pos是否大於1,或者pos超出字符串的長度
	{
		return str;
	}
	if ((p + len - str) > tt)  //len大於pos後剩餘的字符個數
	{
		while (*p)  //那就把pos後面的全部刪掉,直到結束
		{
			*p = '\0';
			p++;
		}
	}

	while (*p && *(p+len))
	{
		*p = *(p + len);
		p++;
	}
	*p = '\0';
	return str;
}
int main()
{
	char string[] = "abcdefg";
	int pos = 0;
	int len = 0;
	int steps = 0;
	printf("string: %s\n", string);
	printf("input pos: ");
	cin >> pos;
	cout << "input len: ";
	cin >> len;
	deleteChars(string, pos, len);
	printf("after delete %d chars behind pos %d: %s\n", len, pos, string);

	return 0;
}

string: abcdefg

input pos: 2
input len: 2
after delete 2 chars behind pos 2: adefg



12.編程實現刪除字符串中所有指定的字符

假設字符串爲“cabcdefcgchci”,把該字符串中所有的字符'c'刪除後,結果爲“abdefghi

//12.編程實現刪除字符串中所有制定的字符
#include<stdio.h>
#include<iostream>
using namespace std;
char * deleteChar(char* str, char c)
{
	char* head = str;
	char* p = str;
	
	if (str == NULL)  //檢查str的有效性
	{
		return NULL;
	}
	while (*p)
	{
		if (*p != c)
		{
			*str = *p; //如果不等於c的值,則記錄在str中
			str++;
		}
		p++;
	}
	*str = '\0';  //結束符
	return head;
}
int main()
{
	char string[] = "cabcdefcgchci";
	char c = 0;
	cout << "input char: ";
	cin >> c;
	cout << "before delete: " << string << endl;
	deleteChar(string, c);  //刪除所有的c
	cout << "after delete: " << string << endl;
	return 0;
}

input char: c

before delete: cabcdefcgchci
after delete: abdefghi



13.編程實現庫函數strcat,實現字符串的拼接

//13.編程實現庫函數strcat,拼接函數
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

char *mystrcat(char *dest, const char* src)
{
	char *ret = dest;//保存目的字符串的首地址,以便返回
	while (*dest)
	{
		dest++;
	}
	while (*src)
	{
		*dest = *src;
		src++;
		dest++;
	}
	*dest = '\0'; //結束符
	return ret;
}
int main()
{
	char *dest = NULL;
	char *str1 = "Hello ";
	char *str2 = "World!";
	dest = (char*)malloc(256);
	*dest = '\0'; //dest裏面是空
	mystrcat(mystrcat(dest, str1), str2);
	cout << "dest: " << dest << endl;
	free(dest);
	dest = NULL;
	return 0;
}

dest: Hello World!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章