C/C++ 字串連接的3種方法

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

  • C 語言的 strcat
  • C++ string 的 append()
  • C++ string 的 += operator

那我們就開始吧!

C 語言的 strcat

C 語言要連接 c-style 字串通常會使用 strcat,要使用 strcat 的話需要引入的標頭檔 <string.h>
strcat 函式原型為

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

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

cpp-string-append.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// g++ cpp-string-append.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] = {0};

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

return 0;
}

結果如下,

1
dest: hello world

如果是使用 std::string 的話,在字串連接上就有一些方便的成員函式可以使用,以下介紹 C++ std::string 字串連接的兩種方式,

C++ string 的 append()

這邊介紹 C++ string 的 append(),std::string 使用 append() 可以連接 std::string 以外也可以連接 c-style 字串,

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

int main() {
string str1 = "hello";
string str2("world");
string str3;

str3.append(str1);
str3.append(" ");
str3.append(str2);

cout << str3 << "\n";

return 0;
}

結果如下,

1
hello world

另外 C++ string 還可以一直使用 append() 串接下去,寫法像這樣,

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

int main() {
string str1 = "hello";
string str2("world");
string str3;

str3.append(str1).append(" ").append(str2);

cout << str3 << "\n";

return 0;
}

C++ string 的 += operator

最後要介紹的是 C++ string 的 += operator,也是最直覺的一種 C++ 字串連接寫法,直接用 += 來連接兩字串,也可以連接 c-style 字串,

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

int main() {
string str1 = "hello";
string str2("world");
string str3;

str3 += str1;
str3 += " ";
str3 += str2;

cout << str3 << "\n";

return 0;
}

結果如下,

1
hello world

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

C++ std::list 用法與範例

本篇 ShengYu 將介紹 C++ std::list 用法與範例,C++ std::list 是一個 double linked list 實作的容器,C++ STL 另外有提供 single linked list 叫做 std::forward_list,list 和 vector 不同的是 list 不支援隨機存取的功能,list 的插入移除操作是常數時間,

以下 C++ list 用法與範例將分為這幾部分,

  • list 常用功能
  • list 初始化
  • list 在尾部新增元素
  • list 在頭部新增元素
  • list for 迴圈遍歷

要使用 list 容器的話,需要引入的標頭檔<list>

list 常用功能

以下為 std::list 內常用的成員函式,
修改器
push_back:把一個元素添加到尾端
push_front:把一個元素插入到頭端
pop_back:移除最後一個元素(尾端)
pop_front:移除第一個元素(頭端)
insert:插入元素
erase:移除某個位置元素, 也可以移除某一段範圍的元素
clear:清空容器裡所有元素
容量
empty:回傳是否為空
size:回傳目前長度
元素存取
front:取得頭部元素
back:取得尾部元素
迭代器
begin:回傳指向第一個元素(頭端)的迭代器
cbegin:回傳指向第一個元素(頭端)的迭代器(const)
end:回傳指向最後一個元素(尾端)的迭代器
cend:回傳指向最後一個元素(尾端)的迭代器(const)
rbegin:回傳指向最後一個元素(尾端)的反向迭代器
crbegin:回傳指向最後一個元素(尾端)的反向迭代器(const)
rend:回傳指向第一個元素(頭端)的反向迭代器
crend:回傳指向第一個元素(頭端)的反向迭代器(const)

list 初始化

C++ std::list 初始化的寫法如下,

1
2
3
4
5
6
7
8
#include <list>
using namespace std;

int main() {
list<int> myList = {1, 2, 3};

return 0;
}

另外一種初始化 list 的方式是根據 C-Style 傳統陣列來 list 初始元素,

1
2
int array[] = {3, 2, 1};
std::list<int> myList(array, array+3);

如果要根據另一個 list 來初始 list 的方法有兩種,一種是使用 = operator,另一種是使用 assign(),使用 = operator 的好處是簡單方便,使用 assign() 的好處是還可以指定要複製範圍,

1
2
3
4
5
std::list<int> myList1 = {1, 2, 3, 4, 5};
std::list<int> myList2;
myList2 = myList1;
// 或者用 assign()
myList2.assign(myList1.begin(), myList1.end());

要初始化 5 個 10 的話可以這樣寫,

1
std::list<int> myList(5, 10);

list 在尾部新增元素

在 list 尾部新增元素的寫法如下,

1
2
std::list<int> myList = {1, 2, 3};
myList.push_back(4);

list 在頭部新增元素

在 list 頭部新增元素的寫法如下,

1
2
std::list<int> myList = {1, 2, 3};
myList.push_front(0);

list for 迴圈遍歷

for 迴圈遍歷 list 的方式有幾種,
首先介紹用 range-based for loop 遍歷 list 並且把元素印出來,寫法如下,

1
2
3
4
5
std::list<int> myList = {1, 2, 3};
for (int n : myList) {
std::cout << n << ", ";
}
std::cout << "\n";

使用 for 迴圈搭配迭代器 iterator,寫法如下,

1
2
3
4
5
6
// for (auto it = myList.begin(); it != myList.end(); it++) {
// or
for (std::list<int>::iterator it = myList.begin(); it != myList.end(); it++) {
std::cout << *it << ", ";
}
std::cout << "\n";

上述是正向迭代器的範例,輸出結果會從 list 頭部印到尾部,
如果要倒過來印,從 list 尾部印到頭部的話,可以使用反向迭代器 reverse_iterator,

1
2
3
4
5
6
// for (auto it = myList.rbegin(); it != myList.rend(); it++) {
// or
for (std::list<int>::reverse_iterator it = myList.rbegin(); it != myList.rend(); it++) {
std::cout << *it << ", ";
}
std::cout << "\n";

參考
[1] std::list - cppreference.com
https://en.cppreference.com/w/cpp/container/list
[2] list - C++ Reference
http://www.cplusplus.com/reference/list/list/

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
std::vector 用法與範例
std::deque 用法與範例
std::queue 用法與範例
std::stack 用法與範例
std::set 用法與範例
std::map 用法與範例
std::unordered_map 用法與範例

Linux cat 讀取檔案用法與範例

本篇 ShengYu 介紹 Linux cat 讀取檔案用法與範例,Linux cat 這個指令的作用是將檔案內容從第一行開始全部顯示在標準輸出(螢幕)上或者也可以用 pipe 的方式串接給別的指令。

cat 檔案

將 file.txt 檔案內容輸出到標準輸出(螢幕),

1
cat file.txt

將 file.txt 檔案內容輸出到標準輸出(螢幕),順便顯示行號,

1
cat -n input.txt

將 file.txt 檔案內容輸出到 file2.txt,

1
cat file.txt > file2.txt

將 file.txt 檔案清空,

1
cat /dev/null > file.txt

cat 檔案後 pipe 給 grep 搜尋

cat 檔案後 pipe 串接導給 grep 搜尋 foo 字串,

1
cat file.txt | grep foo

其它相關文章推薦
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux find 尋找檔案/尋找資料夾用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux tee 同時螢幕標準輸出和輸出到檔案用法與範例
Linux xargs 參數列表轉換用法與範例
Linux tail 持續監看檔案輸出用法與範例
Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例
Linux wget 下載檔案用法與範例

Ubuntu apt-file 指令的用法

本篇 ShengYu 介紹 Ubuntu apt-file 指令的用法,當你知道缺少某個檔案,但不知道該檔案是在 apt 哪個套件中時,就可以用 apt-file search 來搜尋該檔案是在 apt 的哪個套件中,可以搜尋在 apt 管理的檔案,使用前要先安裝一下 apt-file,

1
sudo apt install apt-file

剛安裝完 apt-file 要先 update 一下

1
apt-file update

舉個實際例子,某天我要啟動某程式發現有錯誤訊息,顯示找不到 libQt5SerialPort.so.5

1
error while loading shared libraries: libQt5SerialPort.so.5: cannot open shared object file: No such file or directory

這時使用 apt-file search 來搜尋一下 libQt5SerialPort.so.5 會出現在哪個套件以及的該套件安裝的檔案路徑
$ apt-file search libQt5SerialPort.so.5
libqt5serialport5: /usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5
libqt5serialport5: /usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5.5
libqt5serialport5: /usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5.5.1
根據上述結果,再來查看本機的路徑有沒有這個檔案,發現沒有!
$ ls /usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5
ls: cannot access ‘/usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5’: No such file or directory
所以就可以安裝一下該套件,安裝後再次檢查一下本機的路徑有沒有這個檔案,應該就會有了!

1
2
3
$ sudo apt install libqt5serialport5
$ ls /usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5
/usr/lib/x86_64-linux-gnu/libQt5SerialPort.so.5

Linux dos2unix 轉換 dos 換行字元用法與範例

本篇 ShengYu 介紹 Linux dos2unix 去除 dos 換行字元用法與範例,另外一個相反的指令是 unix2dos。

Windows/Dos 的換行是 \r\n
Linux/Unix 的換行是 \n
所以 Dos 環境下產生的文件拿到 Unix 就需要轉換換行字元,也就是將 \r\n 轉換成 \n,否則會極為不方便,

Ubuntu 安裝 dos2unix 指令

Ubuntu 預設沒安裝 dos2unix 這個指令的話,可以自行透過 apt 來安裝,Ubuntu 要安裝 dos2unix 指令,透過下列指令安裝即可,

1
sudo apt install dos2unix

dos2unix 將 \r\n 轉換成 \n

dos2unix 將 \r\n 轉換成 \n 的指令使用方法如下,將會直接對原檔案 file.txt 直接修改

1
dos2unix file.txt

其它相關文章推薦
Linux 常用指令教學懶人包
Linux cut 字串處理用法與範例
Linux find 尋找檔案/尋找資料夾用法與範例
Linux grep/ack/ag 搜尋字串用法與範例
Linux tee 同時螢幕標準輸出和輸出到檔案用法與範例
Linux xargs 參數列表轉換用法與範例
Linux tail 持續監看檔案輸出用法與範例
Linux du 查詢硬碟剩餘空間/資料夾容量用法與範例
Linux wget 下載檔案用法與範例

Android 取得 WiFi ip address

本篇 ShengYu 介紹 Android 取得 WiFi ip address 的寫法。

1
2
3
4
5
6
7
WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
String ip = String.format("%d.%d.%d.%d",
(ipAddress & 0xff),
(ipAddress >> 8 & 0xff),
(ipAddress >> 16 & 0xff),
(ipAddress >> 24 & 0xff));

加入存取權限,需要在 AndroidManifest.xml 裡加入 android.permission.ACCESS_WIFI_STATE,其他是我可能會用到的也順便加入

1
2
3
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Context WIFI_SERVICE | Android Developers
https://developer.android.com/reference/android/content/Context#WIFI_SERVICE
cameraserve/AndroidManifest.xml at master · arktronic/cameraserve
https://github.com/arktronic/cameraserve/blob/master/app/src/main/AndroidManifest.xml

其它相關文章推薦
Android MJPEG Streaming App

Kotlin print 用法

本篇 ShengYu 介紹 Kotlin print 用法以及在 Android 下的 log 輸出用法。

Kotlin print 用法

Kotlin print 的用法如下,

1
2
3
4
5
6
print("Hello Kotlin") // 不換行
println("Hello Kotlin") // 換行
println("I have " + (2*3) + " books") // Kotlin一樣可以用+來做串接
println("I have ${2*3} books") // 另外可以透過"${"和"}"把需要運算的算式、參數和方法放在這,就可以不用用+來做串接
var i = 2
println("I have ${i*3} books")

可以在 Kotlin 線上編譯器試試,輸出如下,

1
2
3
4
Hello KotlinHello Kotlin
I have 6 books
I have 6 books
I have 6 books

以下順便列出 Java 的寫法,方便對應,

1
2
3
4
5
System.out.print("Hello Java"); // 不換行
System.out.println("Hello Java"); // 換行
System.out.println("I have " + (2*3) + " books"); // 訊息中若有數字運算或是方法呼叫都必須透過+來串接
int i = 2;
System.out.println("I have " + (i*3) + " books");

可以在 Java 線上編譯器試試,輸出如下,

1
2
3
Hello JavaHello Java
I have 6 books
I have 6 books

Android Kotlin Log 用法

在 Android 用 Kotlin 輸出 log 時一樣要使用 Log.x 的方式才會在 adb logcat 上看到輸出,用法如下,

1
2
3
4
5
6
import android.util.Log
// ...
private val TAG = javaClass.simpleName // Kotlin可以不用宣告型態,它會自行判斷
// ...
Log.d(TAG, "Hello Kotlin") //程式碼結尾不需加";"
Log.d(TAG, "I have ${2*3} books") //這裏一樣可以透過"${"和"}"把需要運算的算式、參數和方法放在這

以下順便列出 Java 的寫法,方便對應,

1
2
3
4
5
6
import java.util.Log;
// ...
private final String TAG = getClass().getSimpleName(); // 需要宣告變數型態
// ...
Log.d(TAG, "Hello Java");
Log.d(TAG, "I have " + (2*3) + " books");

線上編譯器
Kotlin Playground: Edit, Run, Share Kotlin Code Online
https://play.kotlinlang.org/
ideone
https://ideone.com/

Ubuntu 安裝 Arduino IDE

本篇 ShengYu 紀錄在 Ubuntu 16.04 下安裝 Arduino IDE,

官網 Arduino IDE 下載連結:https://www.arduino.cc/en/software

目前最新的穩定版本是 Arduino IDE 1.8.15,

官網提供的 Linux 安裝手冊連結:https://www.arduino.cc/en/Guide/Linux

執行 ./install.sh 要用 sudo,否則建立軟連結時會失敗,

1
2
3
4
5
6
7
$ ./install.sh 
Adding desktop shortcut, menu item and file associations for Arduino IDE...


ln: failed to create symbolic link '/usr/local/bin/arduino': Permission denied
Adding symlink failed. Hope that's OK. If not then rerun as root with sudo.
done!

執行成功的輸出如下

1
2
3
4
5
sudo ./install.sh 
Adding desktop shortcut, menu item and file associations for Arduino IDE...


done!

這樣就可以在 Ubuntu Dash 選單找到 arduino 應用程式的圖案了,
移除的話也是要用 sudo 執行唷,sudo ./uninstall.sh

其它參考
如何在Ubuntu上安裝Arduino IDE - Ubuntu問答
https://ubuntuqa.com/zh-tw/article/7920.html

其它相關文章推薦
Ubuntu 安裝 Arduino 遇到的問題

C++ static_cast 的用法

本篇 ShengYu 來介紹 C++ static_cast 的用法,

傳統的強制轉型寫法

傳統的強制轉型寫法如下,有兩種,

1
2
3
(type-id)expression
// 或者
type-id(expression)

實際上的例子,例如強制轉型成 int 的話,

1
2
3
int num2 = (int)num
// 或者
int num2 = int(num)

static_cast 轉型寫法

static_cast 轉型的寫法如下,

1
static_cast<type-id>(expression)

上述的例子使用 static_cast 轉型的寫法就會變成這樣,

1
int num2 = static_cast<int>(num)

其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ 字串轉數字的4種方法
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 用法與範例

Ubuntu/Linux 測試搖桿的工具

本篇 ShengYu 要介紹在 Ubuntu/Linux 下測試搖桿的工具,
我自己的話是會拿來測試我的 PS2 搖桿功能是否正常,

jstest 命令列測試搖桿工具

jstest 是命令列下的測試搖桿工具,安裝指令與使用方式如下,執行程式時,後面接上 device 名稱,例如:/dev/input/js0/dev/input/js1 等等,

1
2
$ sudo apt install joystick
$ jstest /dev/input/js0

使用畫面如下,

jstest-gtk 圖形化測試搖桿工具

使用圖形化工具相對比命令列工具簡單省事許多,jstest-gtk 是圖形化測試搖桿工具,安裝指令與使用方式如下,

1
2
$ sudo apt install jstest-gtk
$ jstest-gtk

使用畫面如下,

其它參考
arduino (19): Use ESP32 to connect PS3 bluetooth controller, you need to connect successfully on windows, and then modify the mac address, then you can connect successfully, but it is currently under test and needs to be paired successfully on windows. - Programmer Sought
https://www.programmersought.com/article/83835337908/

其它相關文章推薦
Windows 10 測試搖桿的工具