【原創】淺談指標(八)字串相關函式(下集)

計算機知識雜談發表於2021-11-19

本文僅在部落格園釋出,認準原文地址:https://www.cnblogs.com/jisuanjizhishizatan/p/15577754.html

前言

字串相關函式(上集)

很多時候,指標對我們寫程式碼會有很大的幫助。例如,下面是一個函式:

#ifdef DEBUG
#define DEBUG_PRINT(arg) debug_print(arg)
#else
#define DEBUG_PRINT(arg) 
#endif
void debug_print(int a[]){
  for(int i=0;i<sizeof(a)/sizeof(int);i++){
    cout<<a[i]<<" ";
  }
}

這個函式目的是要除錯輸出陣列a的內容,然而,這個程式一定無法正常執行,原因之前講過,是指標引數的問題。這裡也請大家自己思考一下。如果還想不出為什麼來,那麼就好好複習之前的內容吧。

練習

這些是對於之前指標主題的練習。如果這幾道題都不會的話,就先好好複習我寫的前幾篇文章吧,這一章是肯定看不懂的。

1.自己編寫memcpy函式,引數如下:

void memcpy(void *dest,void *src,int length);

以位元組為單位,把src中的內容拷貝到dest,長度為length。

2.自己編寫memcmp函式,引數如下:

void memcmp(void *ptr1,void *ptr2,int length);

以位元組為單位,比較記憶體ptr1與ptr2的資料,長度為length。
返回值與strcmp的返回值類似。

由於指標運算的靈活性,函式的實現可以有很多種方式。本次的教程中會給出這裡的一種解法,如果有更多或者更好的解法也可以在評論區指出。

strncmp函式

作用

strncmp(cmdline,"type ",5);

strncmp函式,類似於strcmp函式,用於比較字串。但是,多了一個引數,也就是最後一個引數n,表示只比較n個字元,即使後面的字元不相同,返回值也會相同。例如:
(程式碼摘自《30天自制作業系統》:)

} else if (strcmp(cmdline, "cls") == 0) {
						
} else if (strcmp(cmdline, "dir") == 0) {
						
} else if (strncmp(cmdline, "type ", 5) == 0) {
    for (y = 0; y < 11; y++) {
        s[y] = ' ';
    }
}

中間程式碼很長,我省略掉了。這是該書中,命令列指令的實現程式碼的一部分。其中的type指令,由於寫法是這樣的:

type 檔名

因此,只要前面5個字元"type "相同,就一定是執行type指令。

作用

上面已經舉了30天自制作業系統的例子,就不多說了。

實現

strncmp函式和memcmp函式類似,都是指定長度進行記憶體的比較。這裡就把memcmp的例子寫上去吧。

int _memcmp(char *ptr1,char *ptr2,int n){
	for(int i=0;i<n;i++){
		if(ptr1[i]!=ptr2[i])return ptr1[i]-ptr2[i];
	}
	return 0;
}

strncpy函式

作用

strncpy(str1,"hello world",5);

表示只拷貝第二個引數的前5個字元,多餘的字元將會被忽略。

特性

如果長度不夠,將會出現一些問題。我們來做個試驗:

#include<iostream>
#include<cstring>
using namespace std;
int main(){
	char s[5];
	s[5]=100;
	strncpy(s,"hello",5);
	for(int i=0;i<6;i++){
		printf("%d ",s[i]);
	}
}

在一開始,我們把超出字串長度的部分s[5]設定為100,最終我們輸出字串的每一個數值的時候,發現最終沒有字串結束符,s[5]仍然為100.這就是strncpy的特性——超出指定的長度時候,不會自動新增字串結束符!
因此,strncpy是一個有風險的函式。

自制strncpy

strncpy函式既然有風險,那麼我們也來自己實現一個strncpy函式,並且在最後自動加上'\0'結束符。

void _strncpy(char *s1,char *s2,int n){
	int i=0;
	for(i=0;i<n;i++){
		if(s2[i]==0)return;
		s1[i]=s2[i];
	}
	s1[i]=0;
}

相關文章