發表文章

目前顯示的是 2022的文章

字串連接:strcat()、strncat()

  比照 strcpy()與strncpy() ,做個筆記吧。順帶一提,一副貓樣的cat是concatenate的縮寫。 strncat() 函式宣告 char *strncat(char *dest, const char *src, size_t n); 測試範例 #include <stdio.h> #include <string.h> void main() { char src1[] = "abcd"; char src2[] = "123"; char arr[10]; int i, n; for (n = 0; n < sizeof(arr) - strlen(src1); n++) { memset(arr, '.', sizeof(arr)); strncpy(arr, src1, sizeof(src1)); printf("N = %d: ", n); strncat(arr, src2, n); for (i = 0; i < sizeof(arr); i++) { if (arr[i] == '\0') printf("%c ", '_'); else printf("%c ", arr[i]); } printf("\n"); } } 輸出如下: 顯示「.」代表未改變,保持原始值。 顯示「_」代表字串結尾字元「\0」。 N = 0: a b c d _ . . . . . N = 1: a b c d 1 _ . . . . N = 2: a b c d 1 2 _ . . . N = 3: a b c d 1 2 3 _ . . N = 4: a b c d 1 2 3 _ . . N = 5: a b ...

字串複製:strcpy()、strncpy()

  每次都為了有沒有包含字串結尾字元「\0」而煩惱,就做個筆記吧。 前言:sizeof()與strlen()   進入正題前,先看看字串長度,順便複習陣列和指標。 #include <stdio.h> #include <string.h> void main() { char arr1[] = {'1', '2', '3', '\0'}; char arr2[] = "123"; char *ptr = "123"; printf("--- arr1 ---\n"); printf("length of string : %lu\n", strlen(arr1)); printf("size of array : %lu\n", sizeof(arr1)); printf("--- arr2 ---\n"); printf("length of string : %lu\n", strlen(arr2)); printf("size of array : %lu\n", sizeof(arr2)); printf("--- ptr_arr1 ---\n"); printf("length of string : %lu\n", strlen(&arr1[0])); printf("size of pointer : %lu\n", sizeof(&arr1[0])); printf("--- ptr ---\n"); printf("length of string : %lu\n", strlen(ptr)); printf("size of pointer : %lu\n", sizeof(ptr)); } 輸出如下: ---...

利用lock檔避免程式重複執行

  想直接看lock應用的腳本範例,可以略過第一個範例。 理解鎖檔概念 #!/bin/sh LOCK_FILE=/var/lock/my.lock if [ -f $LOCK_FILE ]; then echo "$0 is running!" >&2 exit 0 fi touch $LOCK_FILE # Start to do my job. sleep 10 echo "Done." rm -f $LOCK_FILE   在無人使用腳本的情況下,開始時新增檔案my.lock,結束時會刪除檔案my.lock;當腳本正在執行中,若重複執行,就會因my.lock檔案存在,而直接結束程式。 使用trap指令   若在執行上方範例,在延遲10秒內,輸入Ctrl + C中斷程式,會發生什麼事呢?因為沒執行到最後一行的刪除my.lock動作,my.lock會一直存在,腳本被鎖住,不能再次執行。為避免程式不正常中斷,而被鎖住的問題,可利用trap指令來執行砍檔。 #!/bin/sh LOCK_FILE=/var/lock/my.lock if [ -f $LOCK_FILE ]; then echo "$0 is running!" >&2 exit 0 fi trap "rm -f $LOCK_FILE" EXIT touch $LOCK_FILE # Start to do my job. sleep 10 echo "Done."   無論何種因素結束程式,當程式結束之前,會發送EXIT訊號,trap攔到EXIT後訊號,就會將my.lock砍掉。這樣做,就能避免程式結束,而my.lock還存在的窘境。 嘗試寫檔取代touch   有沒有一種方法,my.lock不存在時新增,my.lock存在時報錯?利用寫檔的指令能辦到,只要先設定不能覆寫檔案,有檔案存在時,寫檔就會出錯,再判斷出錯跳出程式,就能避免重複執行。 寫一個空檔案的指令為 echo "" >$LOCK_FILE 或者簡化成 echo ...

私有IP

區域網路使用的私有IP,區分為3段,用二進制描述特性: 區段 10.0.0.0 - 10.255.255.255 可用IP 00001010.XXXXXXXX.XXXXXXXX.XXXXXXXX 最大區塊遮罩 11111111.00000000.00000000.00000000 分類預設遮罩 11111111.00000000.00000000.00000000 區段 172.16.0.0 - 172.31.255.255 可用IP 10101100.0001XXXX.XXXXXXXX.XXXXXXXX 最大區塊遮罩 11111111.11110000.00000000.00000000 分類預設遮罩 11111111.11111111.00000000.00000000 區段 192.168.0.0 - 192.168.255.255 可用IP 11000000.10101000.XXXXXXXX.XXXXXXXX 最大區塊遮罩 11111111.11111111.00000000.00000000 分類預設遮罩 11111111.11111111.11111111.00000000 用10進位的IP表示法: 區段 10.0.0.0 - 10.255.255.255 172.16.0.0 - 172.31.255.255 192.168.0.0 - 192.168.255.255 最大區塊...

Linux文件格式常用指令

將\r\n轉換成\n sed -i 's/\r$//g' $FILENAME 效果同dos2unix 去除空格與Tab(\t) sed -i 's/[[:blank:]]*$//g' $FILENAME 效果同trim end

C語言的二維陣列

複習一維陣列 介紹陣列與指標相關的文章實在太多了,我們簡單帶過一維陣列: #include <stdio.h> int main() { const int length = 3; int arr[length]; int i; printf(" arr = %p\n", arr); printf("&arr = %p\n", &arr); printf("size of array: %lu = %lu * %d\n", sizeof(arr), sizeof(int), length); printf("length of array: %ld\n", sizeof(arr) / sizeof(arr[0])); for (i = 0; i < length; i++) arr[i] = i; // Show. for (i = 0; i < length; i++) printf("address %p: value = %d (size = %lu)\n", &arr[i], arr[i], sizeof(arr[i])); return 0; } 輸出如下: arr = 0x7ffdcf290ce0 &arr = 0x7ffdcf290ce0 size of array: 12 = 4 * 3 length of array: 3 address 0x7ffdcf290ce0: value = 0 (size = 4) address 0x7ffdcf290ce4: value = 1 (size = 4) address 0x7ffdcf290ce8: value = 2 (size = 4) 「&arr」與陣列變數「arr」是等價的。 有時遇到長度不固定,可以在長度確定後,再用malloc()配置指標,記得養成好習慣,使用後用free()釋出記憶體,不然在程式結束之前,會一直佔用malloc的記憶體區域。 #inc...

2>&1是什麼意思?介紹輸出重新導向

剛開始接觸shell腳本,看到指令後面接著「2>&1」感到茫然,孰悉輸出重新導向符號「>」,就不難理解,首先要介紹檔案描述符。 檔案描述符 檔案描述符共有3個,1個輸入,2個輸出,如下表 值 stdio.h 名稱 中譯 0 stdin Standar Input 標準輸入 1 stdout Standar Output 標準輸出 2 stderr Standar Error 標準錯誤輸出 將輸出文字記錄於檔案中 將文字記錄於檔案,普遍的寫法為 echo "standar output" > file.txt 其實在「>」前面省略了1,也就是標準輸出(stdout),完整的寫法應為 echo "standar output" 1> file.txt 檔案描述符1是預設值,通常省略不寫,而在「>」後有無空格都是符合語法的,可依個人程式風格自訂。 假設指令輸出有錯誤訊息,例如當前目錄沒有xxx這個檔案,用ls去列出xxx就會出錯,執行顯示為 $ ls xxx ls: cannot access 'xxx': No such file or directory 把標準錯誤輸出(stderr)記錄於檔案中,可寫作 ls xxx 2> file.txt 就可以將「ls: cannot access 'xxx': No such file or directory」存於file.txt。 另一種常見的應用,是想不顯示錯誤訊息,就把標準錯誤輸出丟進/dev/null。 ls xxx 2> /dev/null 導向檔案描述符 若想將「標準輸出」、「標準錯誤輸出」合併,一般的作法是將「標準錯誤輸出」併入「標準輸出」。但若寫為 ls xxx 2>...

tee指令:儲存且同時顯示於螢幕

圖片
tee tee就是指大寫「T」的形狀,左端輸出結果(stdout)進入,右端繼續處理,多了下端儲存至檔案。參考 維基百科 的示意圖 螢幕 & 檔案 想將執行結果儲存於檔案中,可使用「>」達到目的,例如: ls -l > file.txt 但這樣輸出文字就只傳送到file.txt,螢幕不會顯示,藉由tee指令可以讓螢幕同步顯示結果: ls -l | tee file.txt 若是想附加到文件之後 ls -l >> file.txt 螢幕同步顯示則加入參數「-a」 ls -l | tee -a file.txt 變數 & 螢幕 想將執行結果儲存於變數,例如: var=$(ls -l) 但這樣輸出文字螢幕也不會顯示,藉由tee指令讓輸出文字寫到/dev/tty,就可以讓螢幕顯示。 var=$(ls -l | tee /dev/tty) 或者使用「偽終端(/dev/pty/)」達成螢幕顯示的需求,可使用tty指令找到當前的偽終端。 my_tty=$(tty) var=$(ls -l | tee $my_tty)