C/C++ memcpy 用法與範例

本篇 ShengYu 介紹 C/C++ memcpy 用法與範例,memcpy 是用來複製一段記憶體區塊的函式,以下介紹如何使用 memcpy 函式。

C/C++ 使用 memcpy 來複製一段記憶體區塊,也可以用來複製任何資料類型,要使用 memcpy 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
memcpy 函式原型為

1
void * memcpy(void * destination, const void * source, size_t num);

memcpy() 將 source 指向的記憶體區塊複製 num 個到 destination 指向的記憶體區塊,
memcpy 跟 strcpy 不同的是 strcpy 遇到 \0 結束字元就停止複製了,所以 strcpy() 只能用來複製字串,來看看下面的 memcpy 用法範例吧!

一開始先宣告一個 Student 結構的變數 student,然後初始化 student 的 id 與 name 屬性,複製 name 時可以使用 memcpy 或 strcpy,之後再用 memcpy 把整個 student 複製到 student2,

cpp-memcpy.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// g++ cpp-memcpy.cpp -o a.out
#include <stdio.h>
#include <string.h>

struct Student {
int id;
char name[64];
};

int main() {
struct Student student;
student.id = 123456;

char name[] = "Tom";
memcpy(student.name, name, strlen(name)+1);
// or strcpy(student.name, name);
printf("student: %d, %s\n", student.id, student.name);

struct Student student2;
memcpy(&student2, &student, sizeof(student));
printf("student2: %d, %s\n", student2.id, student2.name);
return 0;
}

結果如下,

1
2
student: 123456, Tom
student2: 123456, Tom

以上就是 C/C++ memcpy 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
memcpy - C++ Reference
https://www.cplusplus.com/reference/cstring/memcpy/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ memset 用法與範例
C/C++ memcmp 用法與範例
C/C++ strcpy 用法與範例

C/C++ memset 用法與範例

本篇 ShengYu 介紹 C/C++ memset 用法與範例,memset 是用來對一段記憶體區塊全部設定為某個值的函式,以下介紹如何使用 memset 函式。

C/C++ 使用 memset 來對一段記憶體區塊全部設定為某個值,通常設為 0,要使用 memset 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
memset 函式原型為

1
void * memset(void * ptr, int value, size_t num);

ptr:指向要設定的記憶體區塊的指標。
value:要設定的值,通常是一個 int 整數,但它會被轉換成 unsigned char 類型來填充記憶體區塊。
num:要設定的 byte 數。

memset() 將 ptr 指向的記憶體區塊全部設定成 value,num 為設定的數量,來看看下面的 memset 用法範例吧!

memset 最基本的用法就是設定成 0,如下範例,

cpp-memset.cpp
1
2
3
4
5
6
7
8
9
10
// g++ cpp-memset.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
char arr[10];
memset(arr, 0, sizeof(arr));
printf("%s\n", arr);
return 0;
}

memset 一般用來初始化字串全部設成 \0 字元或者 0,可以順便看看 memset 其他種用法,其它用法如下,

cpp-memset2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// g++ cpp-memset2.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
char str1[32] = "hello world";
memset(str1, '\0', 32); // or memset(str1, 0, 32);
printf("%s\n", str1);

printf("---\n");

char str2[] = "hello world";
memset(str2, 'a', 3);
printf("%s\n", str2);

printf("---\n");

char str3[] = "hello world";
memset(str3+5, 0, 6);
printf("%s\n", str3);
return 0;
}

結果如下,

1
2
3
4
5

---
aaalo world
---
hello

錯誤的 memset 用法

對字元陣列初始化使用 memset 是很常見的用法,但如果換成對整數陣列的話呢?
使用 memset 來對 int 整數陣列初始化是無效的,因為 memset 的單位是 byte,整數陣列要使用迴圈迭代來初始化數值,

假設我們想要將 num 整數陣列都初始化為 1 的話,正確用法應該是迴圈迭代 num 陣列來初始化數值,而不是使用 memset,

cpp-memset3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// g++ cpp-memset3.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
int num[3];
memset(num, 1, 3); // 錯誤的用法
for (int i = 0; i < 3; i++) {
printf("%d\n", num[i]);
}

for (int i = 0; i < 3; i++) {
num[i] = 1;
}

for (int i = 0; i < 3; i++) {
printf("%d\n", num[i]);
}

return 0;
}

結果如下,

1
2
3
4
5
6
65793
-376670744
32766
1
1
1

以上就是 C/C++ memset 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
memset - C++ Reference
https://www.cplusplus.com/reference/cstring/memset/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ memcpy 用法與範例
C/C++ memcmp 用法與範例

C/C++ strcmp 用法與範例

本篇 ShengYu 介紹 C/C++ strcmp 用法與範例,strcmp 是用來判斷兩個字串是否相同的函式,以下介紹如何使用 strcmp 函式。

C/C++ 要判斷 c-style 字串是否相同可以使用 strcmp,要使用 strcmp 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strcmp 函式原型為

1
int strcmp(const char * str1, const char * str2);

strcmp() 如果判斷兩字串相同的話會回傳 0,這必須牢記因為很容易混搖,很多程式 bug 就是這樣產生的,所以 if (strcmp(str1, str2)) printf("not equal\n"); 這樣寫的話結果會是 not equal 唷!來看看下面的 strcmp 用法範例吧!

cpp-strcmp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// g++ cpp-strcmp.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
const char *str1 = "hello world";
const char *str2 = "hello world";

if (strcmp(str1, str2) == 0) {
printf("equal\n");
} else {
printf("not equal\n");
}

return 0;
}

結果如下,

1
equal

再來看看字串不相同的例子,strcmp 是大小寫都判斷不同的,

cpp-strcmp2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// g++ cpp-strcmp2.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
const char *str1 = "hello world";
const char *str2 = "HELLO WORLD";

int ret = strcmp(str1, str2);
if (ret > 0) {
printf("str1 is greater than str2\n");
} else if (ret < 0) {
printf("str1 is less than str2\n");
} else { // ret == 0
printf("str1 is equal to str2\n");
}

return 0;
}

結果如下,

1
str1 is greater than str2

以上就是 C/C++ strcmp 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strcmp - C++ Reference
https://www.cplusplus.com/reference/cstring/strcmp/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ 字串比較的3種方法
C/C++ strncmp 用法與範例
C/C++ memcmp 用法與範例

C/C++ strcpy 用法與範例

本篇 ShengYu 介紹 C/C++ strcpy 用法與範例,strcpy 是用來複製字串的函式,另外有個 strncpy 函式也是同樣功能,但安全性更高,在下列文章一併一起介紹。

C 語言要複製 c-style 字串可以使用 strcpy,要使用 strcpy 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strcpy 函式原型為

1
char * strcpy(char * destination, const char * source);

strcpy 會將 source 複製到 destination 裡,包含 \0 結束字元,並且遇到 \0 結束字元就停止複製,
除了 strcpy 以外,像 strlen 這種函數在操作字串時, 也都會需要用字串最後的 \0 結束字元當做字串結束的判斷,
以下來看看 strcpy 怎麼複製字串,

cpp-strcpy.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// g++ cpp-strcpy.cpp -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strcpy

int main() {
char str[] = "Hello world";
char str2[64];
strcpy(str2, str);
printf("%s\n", str2);

char str3[64];
strcpy(str3, "This is a string");
printf("%s\n", str3);
return 0;
}

結果如下,

1
2
Hello world
This is a string

常見考題

請問下列程式有什麼問題?

1
2
3
char* src = "0123456789";
char dst[10];
strcpy(dst, src);

問題在於 dst 分配了 10 大小的 char 字元陣列 char dst[10]; 總共有 10 個位置,而 src 字串實際佔 11 字元空間(包含結束字元),strcpy 時會造成 buffer overflow,意思就是 0123456789 這個字串 需要 11 個字元的位置才夠放,

在實務上通常會需要儘量少用 strcpy, 而改用 strncpy,strncpy 比 strcpy 多了第三個引數,第三個引數是傳入要複製幾個字元的數量,
所以我們這邊複製字串時最大長度不應超過 dst 的大小,

1
2
strncpy(dst, src, sizeof(dst)-1);
dst[sizeof(dst)-1] = '\0';

範例程式如下,

cpp-strcpy-strncpy.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ cpp-strcpy-strncpy.cpp -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strncpy

int main() {
char* src = "0123456789";
char dst[10];

strncpy(dst, src, sizeof(dst)-1);
dst[sizeof(dst)-1] = '\0';

printf("%s\n", dst);
return 0;
}

輸出結果如下,

1
012345678

以上就是 C/C++ strcpy 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strcpy - C++ Reference
https://www.cplusplus.com/reference/cstring/strcpy/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ memcpy 用法與範例
C/C++ strncpy 用法與範例
C/C++ strcmp 用法與範例
C/C++ strcat 用法與範例
C/C++ strstr 用法與範例
C/C++ strtok 用法與範例

C/C++ strcat 用法與範例

本篇 ShengYu 介紹 C/C++ strcat 用法與範例,strcat 是用來連接兩個字串,或相加兩個字串的函式,以下介紹如何使用 strcat 函式。

C/C++ 要連接 c-style 字串可以使用 strcat 來完成,要使用 strcat 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strcat 函式原型為

1
char * strcat(char * destination, const char * source);

strcat() 會將 source 字串連接在 destination 字串後,來看看下面的 strcat 用法範例吧!

如下範例,宣告一個 dest 後,用 memset() 初始化 dest 後,使用 strcat 將 str1 字串連接在 dest 字串後,之後再連接一個空格,最後再連接 str2,

cpp-strcat.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-strcat.cpp -o a.out
#include <stdio.h>
#include <string.h>
using namespace std;

int main() {
const char *str1 = "hello";
const char *str2 = "world";
char dest[64];

memset(dest, 0, sizeof(dest));
strcat(dest, str1);
strcat(dest, " ");
strcat(dest, str2);
printf("dest: %s\n", dest);

return 0;
}

結果如下,

1
dest: hello world

新手常見的問題

以下是很多新手常常發生的一些問題,
請問以下範例有沒有問題?

1
2
char *str = "Hello ";
strcat(str, "World");

乍看沒問題,但這問題可大了,原因是 str 是一個指標,指向的 “Hello “ 是 const char *,不是一個字元陣列,

所以要怎麼改?答案如下,就是「分配一個夠大的字串陣列」,以下以 128 為例,而且同時要記得這個字元陣列要能夠塞得下你總共的字串,

1
2
char str[128] = "Hello ";
strcat(str, "World");

也可以將 str 用 malloc() 配置一塊記憶體,再使用 strcat 連接字串,

1
2
3
4
5
char *str = (char *) malloc(sizeof(char) * 32);
strcat(str, "Hello ");
strcat(str, "World");

free(str);

以上就是 C/C++ strcat 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strcat - C++ Reference
https://www.cplusplus.com/reference/cstring/strcat/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ 字串連接的3種方法
C/C++ strcmp 用法與範例
C/C++ strtok 用法與範例
C/C++ strstr 用法與範例
C/C++ strcpy 用法與範例

C/C++ strtok 用法與範例

本篇 ShengYu 介紹 C/C++ strtok 用法與範例,strtok 是用來作字串分割的函式,以下介紹如何使用 strtok 函式。

C/C++ 要字串分割可以使用 strtok 來完成,要使用 strtok 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strtok 函式原型為

1
char * strtok(char * str, const char * delimiters);

strtok() 會將 str 依據給入的 delimiters (分割符號/分隔符號) 進行字串分割,如果成功的話會回傳指向分割結果的字串開頭,否則會回傳 NULL,來看看下面的 strtok 用法範例吧!

如下範例所示,d 是分割符號/分隔符號,這邊示範用空格與逗號進行分割,如果有需要的話還可以在 delimiters 加入更多的分割符號,
p 是指向每次分割的結果,
要注意的是除了第一次是將 str 帶入 strtok 分割以外,第二次以上都是將 NULL 帶入 strtok 繼續作字串分割,

cpp-strtok.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// g++ cpp-strtok.cpp -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strtok

int main() {
char str[] = "Hello world, nice to meet you";
const char* d = " ,";
char *p;
p = strtok(str, d);

while (p != NULL) {
printf("%s\n", p);
p = strtok(NULL, d);
}
return 0;
}

結果如下,

1
2
3
4
5
6
Hello
world
nice
to
meet
you

因為 strtok 的實做原理是發現分割字元時,就把字元改為 \0 字元,意味著使用 strtok() 完後,原字串會被修改,
修改後的結果是 Hello\nworld\n\nnice\nto\nmeet\nyou 這樣的形式,所以原本的字串如果之後另有用途的話,記得先複製一份。

這邊我們先將 str 使用 strcpy() 複製一份到 str2 裡,並且在程式的最後分別印出 str 與 str2 看看,

cpp-strtok2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// g++ cpp-strtok2.cpp -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strtok

int main() {
char str[] = "Hello world, nice to meet you";
char str2[64];
strcpy(str2, str);

const char* d = " ,";
char *p;
p = strtok(str, d);

while (p != NULL) {
printf("%s\n", p);
p = strtok(NULL, d);
}

printf("---\n");
printf("%s\n", str);
printf("%s\n", str2);
return 0;
}

結果如下,str 字串已經被修改了,原本 Hello 後面的空格被修改成 \0 字元,所以印出 str 字串只會看到 Hello,

1
2
3
4
5
6
7
8
9
Hello
world
nice
to
meet
you
---
Hello
Hello world, nice to meet you

以上就是 C/C++ strtok 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strtok - C++ Reference
https://www.cplusplus.com/reference/cstring/strtok/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ 字串分割的3種方法
C/C++ strcmp 用法與範例
C/C++ strcat 用法與範例
C/C++ strstr 用法與範例
C/C++ strcpy 用法與範例

std::min_element 用法與範例

本篇介紹 C++ std::min_element 的用法與範例,

傳統陣列用 std::min_element

以下為傳統陣列使用 std::min_element 的用法,

std-min_element.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
// g++ std-min_element.cpp -o a.out
#include <iostream>
#include <algorithm>

using namespace std;

int main() {
int num[] = {3, 1, -14, 1, 5, 9};
int len = sizeof(num) / sizeof(int);
std::cout << "min element: " <<
*std::min_element(num, num+len) << "\n";
return 0;
}

輸出:

1
min element: -14

vector 用 std::min_element

以下是在 C++ vector 容器裡使用 std::min_element 找最小值的範例,std::min_element 會回傳一個迭代器,這個迭代器會指向該容器範圍內最小值的元素,

std-min_element2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ std-min_element2.cpp -o a.out -std=c++11
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
std::vector<int> v{3, 1, -14, 1, 5, 9};
std::vector<int>::iterator result;

result = std::min_element(v.begin(), v.end());
std::cout << "min element: " << *result << "\n";
return 0;
}

進階(懶人)寫法,直接跳過迭代器

這是比較進階(懶人)的寫法,直接回傳指向的元素並且複製到新的 min 變數裡,

std-min_element3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// g++ std-min_element3.cpp -o a.out -std=c++11
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
std::vector<int> v{3, 1, -14, 1, 5, 9};

int min = *std::min_element(v.begin(), v.end());
std::cout << "min element: " << min << "\n";
return 0;
}

以上就是 std::min_element 用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其他參考
std::min_element - cppreference.com
https://en.cppreference.com/w/cpp/algorithm/min_element
min_element - C++ Reference
http://www.cplusplus.com/reference/algorithm/min_element/

其它相關文章推薦
C/C++ 新手入門教學懶人包
std::min 用法與範例
C++ virtual 的兩種用法
C/C++ 字串反轉 reverse
C/C++ call by value傳值, call by pointer傳址, call by reference傳參考 的差別
C++ 類別樣板 class template
std::sort 用法與範例
std::find 用法與範例
std::queue 用法與範例
std::map 用法與範例

C/C++ strstr 用法與範例

本篇 ShengYu 介紹 C/C++ strstr 用法與範例,strstr 是用來作搜尋字串的函式,以下介紹如何使用 strstr 函式。

C/C++ 要搜尋字串可以使用 strstr 來完成,要使用 strstr 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strstr 函式原型為

1
char * strstr(char * str1, const char * str2);

strstr() 會將 str1 字串搜尋 str2 字串,有找到會回傳指向 str1 的指標並且指向第一次符合的位置,沒找到會回傳 NULL,來看看下面的 strstr 用法範例吧!

cpp-strstr.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ cpp-strstr.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
char str[] = "This is a c-style string";
char *pch;
pch = strstr(str, "c-style");
if (pch != NULL)
printf("found: %s\n", pch);
else
printf("not found\n");

return 0;
}

結果如下,

1
found: c-style string

以上就是 C/C++ strstr 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strstr - C++ Reference
https://www.cplusplus.com/reference/cstring/strstr/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ 字串搜尋的3種方法
C/C++ strcmp 用法與範例
C/C++ strcat 用法與範例
C/C++ strtok 用法與範例
C/C++ strcpy 用法與範例

C/C++ 3個求最小值的方法

本篇介紹 C/C++ 3 個求最小值的方法,分別為兩數求最小值、傳統陣列求最小值以及 C++ vector 求最小值。

兩數求最小值的方法

以下為兩數中求最小值的方法,要自己寫一個 min 函式也不是不行,只是如果想快速開發的話,使用 std::min 會方便快速些,不需要遇到每種類型的 min 都要寫一遍,使用 std::min 即可應付各種變數類型,

cpp-find-min-value.cpp
1
2
3
4
5
6
7
8
9
10
11
12
// g++ cpp-find-min-value.cpp -o a.out
#include <iostream>
#include <algorithm>

using namespace std;

int main() {
cout << std::min(3, 5) << "\n";
cout << std::min(10, 6) << "\n";
cout << std::min(15.6f, 17.1f) << "\n";
return 0;
}

輸出:

1
2
3
3
6
15.6

以上面的例子,整數與浮點數都能處理,
關於 C++ std::min 的更詳細的用法與範例可參考我之前寫的這篇

傳統陣列求最小值的方法

以下為標準 C 在陣列中求最小值的方法,
一開始準備好一個陣列後,接下來就是在這個陣列中找出最小值,先將 min 值等於陣列的第一個值,如果一路尋找下來都沒有比這個值還小的話,那麼它就是最小值。

接下來用迴圈在 num 裡尋找有沒有比當前的 min 值還要小的數值,有的話就更新一下目前最小的 min 值。

等到迴圈迭代完後,該 min 值就是這個陣列中的最小值了。

cpp-find-min-value2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ cpp-find-min-value2.cpp -o a.out
#include <iostream>

using namespace std;

int main() {
int num[6] = {4,2,-6,5,1,3};
int min = num[0];
for (int i=1; i<6; i++) {
if (num[i] < min)
min = num[i];
}
cout << "min: " << min << "\n";
return 0;
}

輸出:

1
min: -6

C++ vector 求最小值的方法

以下為 C++ vector 求最小值的方法,使用 C++ 的好處是內建的 STL 有很多函式庫供你使用,但前提是要會使用,就像有車子可開但不會開車也是枉然,但學會開車能讓你比起走路或騎車達到目的地的時間大幅縮短,寫程式遇到要急迫快速開發的情況時,這時對於 STL 的掌握精準度就變得很重要,以下就來示範使用 C++ std::min_element 在 vector 容器裡求最小值,

宣告好 vector 容器並初始化填好元素後,使用 std::min_element 並指定範圍是 v 的最頭部到最尾部,完畢後的 result 迭代器就是指向最小值的元素了,

cpp-find-min-value3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// g++ cpp-find-min-value3.cpp -o a.out -std=c++11
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
std::vector<int> v{4,2,-6,5,1,3};
std::vector<int>::iterator result;

result = std::min_element(v.begin(), v.end());
std::cout << "min element: " << *result << "\n";
return 0;
}

輸出結果同上。

關於 C++ std::min_element 更詳細的用法與範例請看這篇

其他參考
std::min_element - cppreference.com
https://en.cppreference.com/w/cpp/algorithm/min_element
min_element - C++ Reference
http://www.cplusplus.com/reference/algorithm/min_element/

其它相關文章推薦
C/C++ 新手入門教學懶人包
std::min_element 用法與範例
std::min 用法與範例
C++ virtual 的兩種用法
C/C++ 字串反轉 reverse
C/C++ call by value傳值, call by pointer傳址, call by reference傳參考 的差別
C++ 類別樣板 class template
std::sort 用法與範例
std::find 用法與範例
std::queue 用法與範例
std::map 用法與範例

C/C++ 字串分割的3種方法

本篇 ShengYu 介紹 C/C++ 字串分割的3種方法,寫程式中字串分割是基本功夫,而且也蠻常會用到的,所以這邊紀錄我曾經用過與所知道的字串分割的幾種方式,
以下為 C/C++ 字串分割的內容章節,

  • C 語言的 strtok
  • C++ std::string::find() 與 std::string::substr() 完成字串分割功能
  • C++ std::getline() 完成字串分割功能

那我們就開始吧!

C 語言的 strtok

C 語言要字串分割通常會使用 strtok,要使用 strtok 的話需要引入的標頭檔 <string.h>,如果要使用 C++ 的標頭檔則是引入 <cstring>
strtok 函式原型為

1
char * strtok(char * str, const char * delimiters);

strtok() 會將 str 依據給入的 delimiters (分割符號/分隔符號) 進行字串分割,如果成功的話會回傳指向分割結果的字串開頭,否則會回傳 NULL,來看看下面的 strtok 用法範例吧!

如下範例所示,d 是分割符號/分隔符號,這邊示範用空格與逗號進行分割,如果有需要的話還可以在 delimiters 加入更多的分割符號,
p 是指向每次分割的結果,
要注意的是除了第一次是將 str 帶入 strtok 分割以外,第二次以上都是將 NULL 帶入 strtok 繼續作字串分割,

cpp-string-split.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// g++ cpp-string-split.cpp -o a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strtok

int main() {
char str[] = "Hello world, nice to meet you";
const char* d = " ,";
char *p;
p = strtok(str, d);

while (p != NULL) {
printf("%s\n", p);
p = strtok(NULL, d);
}
return 0;
}

結果如下,

1
2
3
4
5
6
Hello
world
nice
to
meet
you

因為 strtok 的實做原理是發現分割字元時,就把字元改為 \0 字元,意味著使用 strtok() 完後,原字串會被修改,
修改後的結果是 Hello\nworld\n\nnice\nto\nmeet\nyou 這樣的形式,所以原本的字串如果之後另有用途的話,記得先複製一份。

C++ std::string::find() 與 std::string::substr() 完成字串分割功能

這邊介紹使用 C++ 的 std::string::find()std::string::substr() 來完成字串分割的功能,std::string::find() 可以用來作字串搜尋的功能,之前在這篇有介紹過了,再將每次找到的位置搭配 std::string::substr() 取出子字串並放入 std::vector 裡,最後再回傳這個結果 std::vector<std::string> result,這種方式的好處是原字串不會被修改,

cpp-string-split2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// g++ cpp-string-split2.cpp -o a.out
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const std::vector<std::string> split(const std::string& str, const std::string& pattern) {
std::vector<std::string> result;
std::string::size_type begin, end;

end = str.find(pattern);
begin = 0;

while (end != std::string::npos) {
if (end - begin != 0) {
result.push_back(str.substr(begin, end-begin));
}
begin = end + pattern.size();
end = str.find(pattern, begin);
}

if (begin != str.length()) {
result.push_back(str.substr(begin));
}
return result;
}

int main() {
std::string str = " This is a c++ string";
std::string pattern = " ";

std::vector<std::string> ret = split(str, pattern);

for (auto& s : ret) {
cout << s << "\n";
}
return 0;
}

結果輸出如下,

1
2
3
4
5
This
is
a
c++
string

C++ std::getline() 完成字串分割功能

這邊介紹使用 C++ 的 std::getline() 來完成字串分割的功能,先將 std::string 建立 std::stringstream,再用 std::getline() 來處理std::stringstream,將每一次取出的字串放到 std::vector,最後再回傳這個結果 std::vector<std::string> result,這種方式的好處是原字串不會被修改,

cpp-string-split3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// g++ cpp-string-split3.cpp -o a.out
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
using namespace std;

const std::vector<std::string> split(const std::string &str, const char &delimiter) {
std::vector<std::string> result;
std::stringstream ss(str);
std::string tok;

while (std::getline(ss, tok, delimiter)) {
result.push_back(tok);
}
return result;
}

int main() {
std::string str = "This is a c++ string";
std::vector<std::string> ret = split(str, ' ');

for (auto& s : ret) {
cout << s << "\n";
}
return 0;
}

結果如下,

1
2
3
4
5
This
is
a
c++
string

以上就是 C/C++ 字串分割的3種方法介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
strtok - C++ Reference
https://www.cplusplus.com/reference/cstring/strtok/
string::find - C++ Reference
https://www.cplusplus.com/reference/string/string/find/
std::getline - cppreference.com
https://en.cppreference.com/w/cpp/string/basic_string/getline

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ 字串比較的3種方法
C/C++ 字串連接的3種方法
C/C++ 字串搜尋的3種方法