1. 程式人生 > >c語言對字串逆序反轉去除空格

c語言對字串逆序反轉去除空格

strstr_while模型

看這篇https://blog.csdn.net/viafcccy/article/details/84886885

兩頭堵模型

將一個這種形式的“        zxcv      ”求出多少個空格並且去除

這裡要用到一個isspace() 

若引數c為空格字元,則返回TRUE,否則返回NULL(0)。就是這麼簡單

 

思路大概是這樣

通過指標從兩端遍歷達到目的

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>

int getCount(char * str,int * pCount)
{
char *p = str;
int ncount = 0;
int i,j = 0;
i = 0;
j = strlen(p);
while(isspace(p[i]) && p[i] != '\0')
{
    i++;
}
while(isspace(p[j-1]) && p[j-1] != '\0')
{
    j--;
}
ncount = j - i ;
*pCount = ncount;
return 0;
}

int trimSpace(char * str,char * newstr)
{
char * p = str;
int ncount = 0;
int i,j = 0;
i = 0;
j = strlen(p)-1;
while(isspace(p[i]) && p[i] != '\0')
{
    i++;
}
while(isspace(p[j]) && p[j] != '\0')
{
    j--;
}
ncount = j - i + 1;
strncpy(newstr , str + i , ncount);
newstr[ncount] = '\0';
return 0;
}

int main()
{
char *p = "   abcdefg   ";
char buf[1024] = {0};
int num = 0;

getCount(p , &num);
trimSpace(p , buf);

printf("nount:%d\n",num);
printf("buf:%s\n",buf);

system("pause");
return 0;
}

這裡又有一個容易宕機的誤區就是

原因是此時對字串指直接操作 但是字串是在全域性區受到作業系統保護不能通過我們修改 就會宕機

所以要注意 是否可以修改

 

字串反轉(逆序)

方法1指標

#include<stdio.h>
#include<string.h>

void main()
{

char buf[] = "abcdefg";
int length = strlen(buf);

char *p1 = buf;
char *p2 = buf + length - 1;//指向末尾

while(p1 < p2)
{
    char c = *p1;
	*p1 = *p2;
	*p2 = c;
	++p1;//直接自增過的值去執行
	--p2;
}

printf("%s\n",buf);
}

 進行封裝

#include<stdio.h>
#include<string.h>

int inverse(char * buf)
{
char * p = buf;
int length = strlen(p);

char *p1 = p;
char *p2 = p + length - 1;//指向末尾

while(p1 < p2)
{
    char c = *p1;
	*p1 = *p2;
	*p2 = c;
	++p1;//直接自增過的值去執行
	--p2;
}
return 0;
}

void main()
{

char buf[] = "abcdefg";
inverse(buf);
printf("%s\n",buf);
}

方法2遞迴逆序

原理就是利用函式引數出入棧的規律 

 

#include<stdio.h>
#include<string.h>

int inverse(char * buf)
{
char *p = buf;
if (p ==NULL)
{
    return -1;
}
if(*p == '\0')
{
return 0;
}
inverse(p+1);
printf("%c",*p);
return 0;
}

void main()
{
char buf[] = "abcdefg";
int a;
a = inverse(buf);
if(a != 0)
{
printf("erro:%d",a);
}
}

理解遞迴呼叫主要依靠兩個模型

1.函式引數出入棧區https://blog.csdn.net/viafcccy/article/details/84583386

 

2.函式呼叫模型https://blog.csdn.net/viafcccy/article/details/84673184 

memset()函式主要作用就是初始化陣列

下面我們來寫一個函式利用全域性變數儲存已經逆序排列的字串

#include<stdio.h>
#include<string.h>

char g_buf[128];

int inverse(char * buf)
{
char *p = buf;
if (p ==NULL)
{
    return -1;
}
if(*p == '\0')
{
return 0;
}
inverse(p+1);
//snprintf()
strncat(g_buf,p,1);
return 0;
}

void main()
{
char buf[] = "abcd";
int a ;
memset(g_buf,0,sizeof(g_buf));
a = inverse(buf);
if(a != 0)
{
printf("erro:%d",a);
}
printf("g_buf:%s",g_buf);
}

 但是在多執行緒程式設計的時候如果使用全域性變數可能會造成資源競爭問題會導致亂序

因此下面使用區域性變數進行儲存逆序的字串

#include<stdio.h>
#include<string.h>

char g_buf[128];

int inverse(char * buf,char * bufresult)
{
char *p = buf;
if (p ==NULL||bufresult == NULL)
{
    return -1;
}
if(*p == '\0')
{
return 0;
}
inverse(p+1,bufresult);
strncat(bufresult,p,1);
return 0;
}

void main()
{
char buf[] = "abcd";
char mybuf[1024] = {0};
int a ;
a = inverse(buf,mybuf);
if(a != 0)
{
printf("erro:%d",a);
}
printf("g_buf:%s",mybuf);
}

也memset等於這一句

這裡也就是警示我們對於使用不完的陣列要初始化

但是為什會輸出的是512個燙 和 abcddcba 

也就是說輸出了1024+8個位元組已經超過了規定的buf1024個位元組

 

更多的可以看一下這篇帖子 https://bbs.csdn.net/topics/391828185?locationNum=4