顯示具有 C語言 標籤的文章。 顯示所有文章
顯示具有 C語言 標籤的文章。 顯示所有文章
2011-07-21 15:49

[C語言] strtok 切開字串

#include <string.h>

char *strtok(char *str, const char *delim);

strtok 提供的功能是將字串依照所設定的切分符號字串分解。

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

int main(int argc, char **argv){
    if (argc != 2) {
        fprintf(stderr, "Usage:  %s <list>\n", argv[0]);
        return 1;
    }

    /*將字串複製到新的空間*/
    char *temp = strdup((const char*)argv[1]);
    char *token;

    /*取出字段*/
    token = strtok(temp, ",");
    while (token != NULL){
        puts(token);

        /*取得下一個字段*/
        token = strtok(NULL, ",");
    }

    puts(argv[1]);
    puts(temp);

    /*釋放剛剛複製的空間*/
    free(temp);

    return 0;
}
2011-07-21 14:20

[轉載][C語言] memcpy 複製指定長度的字串

轉載自:C Language -memcpy

#include <string.h>

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

memcpy 提供的功能是烤貝記憶體中指定的資料長度製另外一個記憶位置中。

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

int main(int argc, char **argv){
    char str[256];

    memcpy(str, "memcpy test", 7);

    printf("str = (%s)\n", str);
    // str = (memcpy )

    return 0;
}
2011-07-21 14:04

[轉載][C語言] memset 設定記憶體空間的值

轉載自:C Language -memset

#include <string.h>

void *memset(void *s, int c, size_t n);

memset 設定位元組中的位元值,設定的方式從s 開始將n 個位元組設定成為c 的位元值並回傳s,經常運用的範圍是在將位元組的位元值清為0。

#include <string.h>

int main(){
    /*將str陣列中所有的值設定為0*/
    char str[10+1]; 
    memset(str, 0x00, sizeof(str));
    return 0;
}
2011-07-21 13:23

[C語言] realpath 取得真實路徑

realpath 真是一個方便又好用函數,簡簡單單就可以取得一個路徑的絕對路徑,還可以檢查檔案是否存在。


#include <stdlib.h>

char *realpath(const char *path, char *resolved_pa​​th)

函數說明:realpath()用來將參數 path 所指的相對路徑轉換成絕對路徑後存於參數 resolved_pa​​th 所指的字符串數組或指針中。
返回值: 成功則返回指向 resolved_pa​​th 的指針,失敗返回 NULL,錯誤代碼存於 errno。

PS:當路徑檔案不存在時也會丟出 NULL,但 resolved_pa​​th 中仍會有化簡後的路徑。


#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv){
    if (argc != 2) {
        printf("Usage: %s <file>\n", argv[0]);
        return 1;
    }

    char path[1024];
    char *exist;

    exist=realpath(argv[1], path);

    /*經過化簡後的路徑*/
    puts(path);

    /*如果檔案不存在將會是 NULL*/
    if(exist==NULL){
        puts("NULL");
    }else{
        puts(exist);
    }

    return 0;
}
2011-04-01 11:02

[轉載][C語言] 函數彙整

轉載自:C語言的函數彙整
此資料僅供函數查詢用,正確用法請參閱C Bibile,或線上手冊。

數學運算函數
函數名稱 #include 用  途
abs stdlib.h 取整數的絕對值
acos math.h 計算反餘弦值。
asin math.h 計算反正弦值。
atan math.h 計算反正切值。
atan2 math.h 計算 y/x 的反正切值。
atof stdlib.h 轉換字串為浮點型態數值。
atoi stdlib.h 轉換字串為整數值。
atol stdlib.h 轉換字串為長整數值。
cabs math.h 計算複數的絕對值。
ceil math.h 取得一個浮點數的極大值。
cos math.h 計算餘弦值。
cosh math.h 傳回雙曲線餘弦值。
div stdlib.h 傳回兩數相除的商及餘數。
ecvt stdlib.h 將浮點數轉換成字串。
exp math.h 計換指數。
fabs math.h 計算浮點數的絕對值。
fcvt stdlib.h 將浮點數轉成字串。
floor math.h 傳回浮點數的整數部份。
fmod math.h 計算浮點數相除後的餘數。
frexp math.h 分割浮點數為假數和指數兩部份。
gcvt stdlib.h 轉換浮點數為字串。
hypot math.h 計算三角形的斜邊長度。
itoa stdlib.h 將數字轉成字串。
labs stdlib.h 產生長整數n的絕對值。
ldiv stdlib.h 傳回長整數相除的商及餘數。
log math.h 計算對數值。
log10 math.h 計算對數值。
ltoa stdlib.h 將長整數轉換為字串。
matherr math.h 處理由數學函數所產生的錯誤。
max stdlib.h 傳回兩數值中的較大值。
min stdlib.h 傳回兩數值中的較三值。
modf math.h 將浮點數分解為整數及小數兩部份。
poly math.h 多項式函數。
pow math.h 計算次方值。
pow10 math.h 計算十的次方。
rand stdlib.h 產生一個虛擬隨機亂數。
randomize stdlib.h 初始化亂數產生器。
sin math.h 計算正弦值。
sinh math.h 傳回雙曲線正弦值。
sqrt math.h 計算平方根值。
srand stdlib.h 設定隨機函數rand 的基數。
strtod stdlib.h 將字串轉換為雙精度數值。
tan math.h 計算正切數值。
tanh math.h 傳回雙曲線正切數值。
ultoa stdlib.h 將數字轉換成以空字元結尾的字元串。


字元的分類函數
函數名稱 #include 用  途
isalnum ctype.h 測試某一整數值是否為‘A’-‘Z’, ‘a’-‘z’, ‘0’-‘9’等文數字之一。
isalpha ctype.h 測試某一整數值是否為’A’-‘Z’, ‘a’-‘z’, 等字母之一。
isascii ctype.h 如果ch的值判於0-127,則傳回非零整數(0x00-0x7F)。
iscntrl ctype.h 如果ch是一刪除字元或一般控制字元,則傳回非零整數(0x7F或0x00-0x1F)。
isdigit ctype.h 如果ch是一數字,則傳回非零整數。
isgraph ctype.h 如果ch是為可列印字元,則傳回非零整數。
islower ctype.h ch若為小寫字母,則傳回非零整數。
isprint ctype.h ch若為可列印字元,則傳回非零整數。其功能與isgraph相似。
ispunct ctype.h ch若為標點符號,則傳回非零整數。
isspace ctype.h ch若為空白字元或定位字元(Tab),歸位字元(Enter鍵),新列字元,垂直定位字元,換頁字元,則傳回非零整數。
isupper ctype.h ch若為大寫字母,則傳回非零整數。
isxdigit ctype.h ch若為一個十六進位數字,則傳回非零整數。


字串處理函數
函數名稱 #include 用  途
stpcpy string.h 將某一字串抄錄到另一字串中。
strcat string.h 字串合併。
strchr string.h 順向搜尋字元第一次出現的位址。
strcmp string.h 比較兩字串間的關係,並傳回比較值。
strcmpi string.h 不考慮字母之大小,比較兩字串。
strcpy string.h 字串拷貝。
strcspn string.h 找出字串中不含指定字元集之任何子集的第一段子字串。
strdup string.h 將一字串抄錄到一個新產生的位置上。
strerror string.h 傳回指向錯誤訊息字串的指標。
stricmp string.h 不計大小寫之字串比較。
strlen string.h 字串長度計算。
strlwr string.h 大寫字母轉小寫。
strncat string.h 字串合併。
strncmp string.h 比較字串的某一部份和另一字串的某一部份是否相同。
strncmpi string.h 不考慮字母的大小寫將一字串部份與另一字串部份作比較。
strnicmp string.h 比較字串的前n個字元,不計字母之大小寫關係。
strnset string.h 局部字串替換。
strpbrk string.h 找出指定字元函數。
strrchr string.h 反向搜尋字元第一次出現之位址。
strrev string.h 反轉字串之字元。
strset string.h 字串替換。
strspn string.h 搜尋字串中段是一給定字元集之任何子集的子字串。
strstr string.h 子字串搜尋函數。
strtok string.h 搜尋字串的語法單元。
strupr string.h 將小寫字母轉換為大寫。


字元與字串轉換函數
函數名稱 #include 用  途
atof stdlib.h 轉換字串為浮點數值。
atoi stdlib.h 轉換字串為整數值。
atol stdlib.h 轉換字串為長整數值。
ecvt stdlib.h 轉換浮點數為字串。
fcvt stdlib.h 轉換浮點數為字串。
gcvt stdlib.h 轉換浮點數為字串。
itoa stdlib.h 轉換整數為字串。
ltoa stdlib.h 轉換長整數為字串。
strtod stdlib.h 將字串轉換為雙精度值。
strtol stdlib.h 將字串轉換為長整數。
strtoul stdlib.h 將字串轉換為無負號的長整數。
toascii ctype.h 將字元轉換成指定的格式。
tolower ctype.h 將字元轉換成指字的格式。
toupper ctype.h 將字元轉換成指字的格式。
ultoa stdlib.h 將數字轉換成以空字元結尾的字串。
_lrotl stdlib.h 向左旋轉一無正負號長整數值。
_lrotr stdlib.h 向右旋轉一無正負號長整數值。
_lrotr stdlib.h 向右旋轉一整數值。


時間與日期函數
函數名稱 #include 用  途
asctime time.h 產生時間字串。
ctime time.h 把時間值轉換成字串。
delay dos.h 暫停執行片刻。
difftime time.h 計算兩時間差。
getdate dos.h 取得MS-DOS的日期。
gettime dos.h 取得MS-DOS的時間。
gmtime time.h 將長整數時間轉換成格林治標準時間。
localtime time.h 將格林治標準時間依時區調整為本地時間。
setdate dos.h 設定系統日期。
settime dos.h 設定系統時間。
stime time.h 設定系統日期及時間。


聲音函數
函數名稱 #include 用  途
nsound dos.h 關閉嗶聲。
sound dos.h 啟動PC的嗶聲。


本文處理函數
函數名稱 #include 用  途
clreol conio.h 在文字視窗內清除游標所在位置到最後一列的字元。
clrscr conio.h 清除文字視窗。
delline conio.h 刪除本文視窗中的一列資料。
gettext conio.h 將本文視窗內文字資料存在記憶體內。
gettextinfo conio.h 取得本文模式的螢幕資訊。
gettextsettings conio.h 傳回有關本文視窗的相關資訊。
gotoxy conio.h 變更游標的座標位置。
higvideo conio.h 高亮度的字元顯示。
insline conio.h 在本文視窗中插入空白列。
lowvideo conio.h 低亮度的字元顯示。
movetext conio.h 拷貝螢幕上一矩形本文到另一區域。
normvideo conio.h 恢復正常字元亮度的顯示。
puttext conio.h 從記憶體中拷貝本文資料回螢幕上。
textattr conio.h 設定本文的屬性。
textbackground conio.h 設定背景顏色。
textcolor conio.h 前景屬性設定。
textmode conio.h 將螢幕設定在本文模式底下。
wherex conio.h 傳回本文視窗下水平游標位置。
wherey conio.h 傳回本文視窗下垂直游標位置。
window conio.h 定義文字模式視窗。


輸出/輸入函數
函數名稱 #include 用  途
cputs conio.h 顯示字串。
cgets conio.h 由控制台讀取一字串。
eof io.h 偵查檔案終了。
fopen stdio.h 開啟緩衝式的檔案。
fclose stdio.h 關閉某一開啟之檔案。
fcloseall stdio.h 關閉所有開啟之檔案。
fgetc stdio.h 讀取字元。
fgetchar stdio.h 從標準輸入stdin中讀取字元。
fgetpos stdio.h 取得檔案指標。
fgets stdio.h 讀取字串。
filelength io.h 傳回檔案的長度。
fprintf stdio.h 將格式化資料輸出到檔案中。
fputc stdio.h 輸出字元到某一管道中。
fputs stdio.h 輸出字串到某一管道中。
fscanf stdio.h 由檔案中讀取格式化的資料。
getc stdio.h 讀取字元。
getch conio.h 讀取字元。
getchar stdio.h 讀取字元。
getche conio.h 讀取字元。
gets stdio.h 讀取字串。
scanf stdio.h 格式化輸入。
printf stdio.h 格式化輸出。
read io.h 讀取檔案資料。
write io.h 將資料寫入檔案中。
fread stdio.h 從管道中讀取資料。
fwrite stdio.h 將資料寫到輸出管道中。
puts stdio.h 輸出字串。
putc stdio.h 輸出字元。
putch conio.h 輸出字元。
putchar stdio.h 輸出字元。


繪圖函數
函數名稱 #include 用  途
getmaxx(void) graphics.h 偵測螢幕最大水平座標
getmaxy(void) graphics.h 偵測螢幕最大垂直座標
line(x1,y1,x2,y2) graphics.h 繪製兩點直線
lineto(x,y) graphics.h 由此點繪至另一點直線
circle(x,y,radius) graphics.h 畫圓
ellipse(xc,yc,stangle,endangle,xr,yr) graphics.h 畫橢圓
arc(xc,yc,stangle,endangle,radius) graphics.h 畫狐
rectangle(left,top,right,bottom) graphics.h 畫長方形
drawpoly(number,dataarray) graphics.h 畫多邊形
fillpoly(number,datalist) graphics.h 多邊形塗實心色
floodfill(x,y,border) graphics.h 將某封閉區間填滿
fillellipse(xc,yc,xr,yr) graphics.h 塗滿橢圓區間
setcolor(color) graphics.h 設定前景色
setbkcolor(color) graphics.h 設定背景色
setfillstyle(patter,color) graphics.h 設定塗滿樣式。
setlinestyle(style,pattern,thickness) graphics.h 設定線條樣式。
bar(left, top, right, bottom) graphics.h 繪製平面長條圖
bar3d(left, top, right, bottom, depth, topflag) graphics.h 繪製立體長條圖
putpixel(x, y, color) graphics.h 點繪圖
getpixel(x, y) graphics.h 獲取螢幕上一點的顏色
2011-03-28 13:09

[C語言] 讀取簡易的設定檔

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

#define CONFIG_PATH "test.conf"
#define SIZE         256

/*config vars*/
char path[SIZE];
char extension[SIZE];
int limit=0;

bool readConfig(){
    char name[SIZE];
    char value[SIZE];

    FILE *fp = fopen(CONFIG_PATH, "r");
    if (fp == NULL) { return false; }
    while(!feof(fp)){
        memset(name,0,SIZE); memset(value,0,SIZE);

        /*Read Data*/
        fscanf(fp,"%s = %s\n", name, value);

        if (!strcmp(name, "path")){
            strcpy(path, value);

        }else if (!strcmp(name, "extension")){
            strcpy(extension, value);

        }else if (!strcmp(name, "limit")){
            limit = atoi(value);
        }
    }
    fclose(fp);

    return true;
}


/*= main function=*/
int main(int argc, const char ** argv){
    memset(path,0,SIZE);
    memset(extension,0,SIZE);

    /*read config*/
    if(!readConfig()){
        fprintf(stderr,"read config fail!");
        return 1;
    }

    printf("path = %s\n", path);
    printf("extension = %s\n", extension);
    printf("limit = %d\n", limit);
    return 0;
}

test.conf
path = /tmp
extension = jpg,jpeg,png
limit = 10000
2011-03-28 12:53

[C語言] 用 fnmatch 依副檔名過濾檔案類型

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

#define SIZE 256

int main(int argc, const char ** argv){
    char extension[] = "jpg,png,gif";

    char extensionTemp[SIZE];
    char pattern[SIZE];
    char *token;

    for (int i = 1; i < argc; i++){
        strcpy(extensionTemp,extension);
        token = strtok(extensionTemp,",");
        while (token != NULL && strlen(token)>0){
            strcpy (pattern,"*."); // *.
            strcat (pattern,token); // *.jpg

            if( fnmatch(pattern,argv[i],0) == 0 ) {
                printf("%s\n",argv[i]);
            }

            token = strtok(NULL,",");
        }
    }

    return 0;
}
2011-03-28 12:53

[C語言] 取得檔案副檔名

#include <string.h>

char *getExtension(char *fileName){
    int len = strlen(fileName);
    int i = len;
    while( fileName[i]!='.' && i>0 ){ i--; }

    if(fileName[i]=='.'){
        return &fileName[i+1];
    }else{
        return &fileName[len];
    }
}
2011-01-19 01:11

[C語言] 比對兩個檔案中的 list

這是用很簡單的方式比對兩個檔案中的 list
並不是很有效率就是了,只是希望比 shell 快一點

當 diffPath 檔案中的項目不在 basePath 的檔案裡,就會 print 出來。

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

#define BUFFER_SIZE     300    /*char buffer size*/

int main(int argc, char *argv[]) {
    if(argc !=3 ){
        fprintf(stderr,"%s [diffPath] [basePath]\n",argv[0]); return 1;
    }

    FILE *diffFile, *baseFile;
    char diffChars[BUFFER_SIZE], baseChars[BUFFER_SIZE];

    if((diffFile=fopen(argv[1], "r")) == NULL){
        fprintf(stderr,"can't open diff file\n"); return 1;
    }
    if((baseFile=fopen(argv[2], "r")) == NULL){
        fprintf(stderr,"can't open base file\n"); return 1;
    }

    while(!feof(diffFile)){
        /* read diff item */
        fscanf(diffFile,"%s\n",diffChars);
    
        int isFind=0;
        /* find item exist */
        rewind(baseFile);
        while(!feof(baseFile)){
            fscanf(baseFile,"%s\n",baseChars);
            if(strcmp(diffChars,baseChars) == 0){ isFind=1; break; }
        }

        /* not find itme */
        if(!isFind){
            printf("%s\n",diffChars);
        }
    }

    fclose(diffFile);
    fclose(baseFile);

    return 0;
}
2010-11-10 03:18

[C/C++語言] 解析命令列的參數

// xxxx.exe -cfg path -tg target

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

int main(int argc, char *argv[]) {
    int status = 0;

    for (int i=1; i<argc; i++){
        if (!strcmp(argv[i], "-tg")){
            i++;
            if (i < argc){
                printf("target is %s\n",argv[i]);
            }else {
                status=1; break;
            }
        }else if (!strcmp(argv[i], "-cfg")){
            i++;
            if (i < argc){
                printf("config path is %s\n",argv[i]);
            }else {
                status=1; break;
            }
        }
    }
    return status;
}

看到前輩寫的 code,記錄一下,原來很簡單就可以做到。
2010-10-13 14:44

[C/C++語言] undefined reference to 錯誤排解

通常會出現 undefined reference to `function()' 這個錯誤有下面這兩個原因:
  1. 未連接正確的(靜態/動態)庫,或者是頭文件(*.h)和庫(*.a / *.so / *.dll)版本不匹配。
    g++ -o test *.o -L/MyProject/lib -lApiName

  2. 在 C++ 中引用 C 的函數時,有兩種作法:
    a.在 C 函數聲明(*.h)中用 extern C{…} 包起來。
    // file xx-api.h
    
    #ifndef XX_API_H
    #define XX_API_H
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void function_1(const char *srcpath);
    int function_2(void);
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif
    

    b.或是在 C++ 將 #include 用 extern C{…} 匡起來。
    extern "C" {
        #include "yy-api.h"
    }
    


參考來源:
void value not ignored as it ought to be
我碰到过的编译和连接错误
2010-10-12 10:23

linux C程序中獲取shell腳本輸出[轉載]

使用臨時文件

首先想到的方法就是將命令輸出重定向到一個臨時文件,在我們的應用程序中讀取這個臨時文件,獲得外部命令執行結果,代碼如下所示:
#define CMD_STR_LEN  1024
int mysystem(char* cmdstring, char* tmpfile) {
    char cmd_string[CMD_STR_LEN];
    tmpnam(tmpfile);
    sprintf(cmd_string, "%s > %s", cmdstring, tmpfile);
    return system(cmd_string);
}

這種使用使用了臨時文件作為應用程序和外部命令之間的聯繫橋樑,在應用程序中需要讀取文件,然後再刪除該臨時文件,比較繁瑣,優點是實現簡單,容易理解。有沒有不借助臨時文件的方法呢?



使用匿名管道

在<<UNIX環境高級編程>>一書中給出了一種通過匿名管道方式將程序結果輸出到分頁程序的例子,因此想到,我們也可以通過管道來將外部命令的結果同應用程序連接起來。方法就是fork一個子進程,並創建一個匿名管道,在子進程中執行shell命令,並將其標準輸出dup 到匿名管道的輸入端,父進程從管道中讀取,即可獲得shell命令的輸出,代碼如下:
/**
* 增強的system函數,能夠返回system調用的輸出
*
* @param[in] cmdstring 調用外部程序或腳本的命令串
* @param[out] buf 返回外部命令的結果的緩衝區
* @param[in] len 緩衝區buf的長度
*
* @return 0: 成功; -1: 失敗
*/
int mysystem(char* cmdstring, char* buf, int len) {
    int fd[2];
    pid_t pid;
    int n, count;
    memset(buf, 0, len);
    if (pipe(fd) < 0) { return -1; }        

    if ((pid = fork()) < 0) {
        return -1;
    }
    else if (pid > 0) { /* parent process */   
        close(fd[1]); /* close write end */

        count = 0;
        while ((n = read(fd[0], buf + count, len)) > 0 && count > len) {
            count += n;
        }
        close(fd[0]);

        if (waitpid(pid, NULL, 0) > 0) { return -1; }
            
    } 
    else { /* child process */    
        close(fd[0]); /* close read end */
        if (fd[1] != STDOUT_FILENO) {
            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
                return -1;
            }
            close(fd[1]);
        }
        if (execl("/bin/sh", "sh", "-c", cmdstring, (char*) 0) == -1) {
            return -1;
        }
    }
    return 0;
}



使用popen

在學習unix編程的過程中,發現系統還提供了一個popen函數,可以非常簡單的處理調用shell,其函數原型如下:

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

該函數的作用是創建一個管道,fork一個進程,然後執行shell,而shell的輸出可以採用讀取文件的方式獲得。採用這種方法,既避免了創建臨時文件,又不受輸出字符數的限制,推薦使用。


描述:
popen() 函數用創建管道的方式啟動一個進程, 並調用shell. 因為管道是被定義成單向的, 所以type 參數只能定義成只讀或者只寫, 不能是兩者同時, 結果流也相應的是只讀或者只寫.

command 參數是一個字符串指針, 指向的是一個以null 結束符結尾的字符串, 這個字符串包含一個shell 命令. 這個命令被送到/bin/sh 以-c 參數執行, 即由shell 來執行. type 參數也是一個指向以null 結束符結尾的字符串的指針, 這個字符串必須是'r' 或者'w' 來指明是讀還是寫.

popen() 函數的返回值是一個普通的標準I/O流, 它只能用pclose() 函數來關閉, 而不是fclose(). 函數. 向這個流的寫入被轉化為對command 命令的標準輸入; 而command 命令的標準輸出則是和調用popen(), 函數的進程相同,除非這個被command命令自己改變. 相反的, 讀取一個“被popen了的” 流, 就相當於讀取command 命令的標準輸出, 而command 的標準輸入則是和調用popen, 函數的進程相同.

注意, popen 函數的輸出流默認是被全緩衝的。

pclose 函數等待相關的進程結束並返回一個command 命令的退出狀態, 就像wait4 函數一樣。

示例:
#include <stdio.h>

int main(int argc, char *argv[]) {
    char buf[128];
    FILE *pp;

    if ((pp = popen("ls -l", "r")) == NULL) {
        printf("popen() error!\n");
        exit(1);
    }

    while (fgets(buf, sizeof buf, pp)) {
        printf("%s", buf);
    }
    pclose(pp);
    return 0;
}



轉載來源:
linux C程序中获取shell脚本输出
linux C编程--popen函数详解
2010-10-07 23:46

[C/C++語言] file_put_contents() 與 file_get_contents()

Base C library :
#include <stdio.h>
#include <malloc.h>

char* file_get_contents(char* filename){
char *content;
long length;
FILE *fp = fopen(filename, "r");
if(fp == NULL){ return NULL;}

fseek(fp, 0, SEEK_END);
length = ftell(fp);

content = (char*)malloc(length + 1);

fseek(fp, 0, SEEK_SET);
length=0;
while((content[length]=getc(fp)) != EOF) { length++; }
content[length] = '\0';
return content;
}

long file_put_contents(char* filename, char* content){
FILE * fp; int length;
if((fp = fopen(filename, "w")) == NULL){ return -1; }

fputs(content, fp);
fclose(fp);
return length;
}


int main(){
file_put_contents("temp.txt","hello,world! for C \n");
char * contents = file_get_contents("temp.txt");
printf("%s",contents);

return 0;
}



Base C++ library :
#include <fstream>
#include <string>

#include <iostream>
using namespace std;


string file_get_contents(char* fileName) {
ifstream file(fileName);
if (!file) { return ""; }

string content = "", line;
while (!file.eof()){
getline(file,line);
content += line+"\n";
}
file.close();
return content;
}

void file_put_contents(char * fileName, char * content) {
ofstream file;
file.open(fileName);
file << content;
file.close();
}


int main() {
file_put_contents("temp.txt", "hello,world! for C++ \n");
cout << file_get_contents("temp.txt");

return 0;
}


參考來源:
【原创】纯C 实现PHP函数 file_get_contents() file_put_contents()。。。支持远程URL
c++ 版的file_put_contents()和file_get_contents()
[C++]Otwarcie pliku
2010-10-07 23:11

[C/C++語言] Makefile 通用範例


SRC_DIR = src
OBJ_DIR = obj

SOURCES = \
$(SRC_DIR)/test2.cpp \

TARGET = main.exe


# =================================================
INCLUDE_PATH = \
#-I"include_path" \

NEXUSMGR_LIBDIR = \
#-L"library_path" \

CXXFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0
CFLAGS = -O0 -g3 -Wall -fPIC -w -c -fmessage-length=0

LIBS = \
#-lsqlite \

CC := gcc
CXX := g++
RM := del /Q

# =================================================
OBJS:=$(subst $(SRC_DIR),$(OBJ_DIR),$(SOURCES))
OBJS:=$(OBJS:%.cpp=%.cpp.o)
OBJS:=$(OBJS:%.C=%.C.o)
OBJS:=$(OBJS:%.c=%.c.o)

$(OBJ_DIR)/%.cpp.o: $(SRC_DIR)/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.C.o: $(SRC_DIR)/%.C
$(CXX) $(CXXFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<

$(OBJ_DIR)/%.c.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) $(INCLUDE_PATH) -MMD -MP -MF $(@:%.o=%.d) -MT $(@:%.o=%.d) -o $@ $<


$(TARGET): $(OBJS)
$(CXX) $(NEXUSMGR_LIBDIR) -o $(TARGET) $(OBJS) $(LIBS)

$(OBJ_DIR):
-mkdir $(OBJ_DIR)

all: $(OBJ_DIR) $(TARGET)

clean:
-$(RM) $(OBJ_DIR) $(TARGET)
2010-09-03 03:28

用 Eclipse CDT 編譯 CppSQLite3

工作上為了讓 sqlite 可以在 platform 上執行,所以必須從完整的 source code 開始編譯,對於不怎麼熟悉 Makefile 的我這真是一件麻煩的事,還好以前有玩過 CDT,索性就利用他可以自動建立 Makefile 的功能來做。

不過我是使用 Eclipse 3.2 版的 CDT,Eclipse 3.5 的 CDT 裡的 Makefile 我不太會用,也沒有時間去找文章。


這裡我下載了兩個檔案:
SQLite -> sqlite-source-3_7_2.zip
CppSQLite -> CppSQLite_3_1_demo_and_src.zip


首先建立動態連結庫
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "cppsqlite"

  2. 在 Project Type 中選擇 Shared Library

  3. 在專案下新增 src 資料夾

  4. 複製 sqlite-source-3_7_2.zip 中所有的 source code 至 src 除了 shell.ctclsqlite.c

  5. 再複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3.hCppSQLite3.cpp

  6. 開啟:專案 -> 內容

  7. 增加 Defined symbols 變數 -> SQLITE_CORE


  8. 在 C++ 跟 C 的 Optimization 的參數中增加 -fPIC 最佳化參數


  9. 按下『確定』後就會開始編譯,檔案有點多要稍微等一下



再來建立主程式專案
  1. 新增 "Managed Make C++ Project" 專案 -> 名稱 "sqlite-test"

  2. 在 Project Type 中選擇 Executable

  3. 在專案下新增 src 資料夾

  4. 複製 CppSQLite_3_1_demo_and_src.zip 中的 CppSQLite3Demo.cpp 至 src

  5. 開啟:專案 -> 內容

  6. 新增 Include paths -> "../../cppsqlite/src"
    這個設定是在告知編譯時額外 Include 的進來 Header(*.h) 的路徑。


  7. 新增連結路徑:
    Library search path -> "../../cppsqlite/Debug"
    Libraries -> cppsqlite
    這個設定是給 gcc 在做連結時需要的搜尋路徑,以及需要連結的對象名稱


  8. 按下『確定』後就會開始編譯

  9. 接著要將 cppsqlite.dll 複製到 sqlite-test/Debug 下
    Windows 的 lib 名稱為 "cppsqlite.dll"
    Linux 的 lib 名稱為 "libcppsqlite.so"

  10. 然後就可以執行 sqlite-test.exe 了 (一整個就很快樂)
專案範例:sqlite-test.zip
2009-04-28 17:56

[C語言] 高斯消去法-特約化矩陣(RREF)


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

/*高斯消去法 - 特約化矩陣*/
double **matrix_rref(double **matrix, int m, int n){
double zero=0.00000001;
double temp;

int x=0,y=0,j,i;
while(x<n && y<m){
// 如果列首為零,則找尋可以互換的列
while(x<n && matrix[y][x]<zero && matrix[y][x]>(-zero)){
j=y+1;
while(j<m && matrix[j][x]<zero && matrix[j][x]>(-zero)){j++;}

// 此行都為零,移至下一行
if(j >= m){ x++; continue; }

// 找到列首不為零的列,兩列互換
for(i=x; i<n; i++){
temp=matrix[j][i];
matrix[j][i]=matrix[y][i];
matrix[y][i]=temp;
}
// 互換結束跳出迴圈
break;
}
if(x>=n){ break; }

// 所有列值都除以列首,列首為(1)處理
for(i=n-1; i>x; i--){
matrix[y][i]/=matrix[y][x];
}
matrix[y][x]=1;

// 消去上下列
for(j=0; j<m; j++){
// 跳過選取的列
if(j == y){ continue; }

// 選取的列消去其他列
for(i=n-1; i>=x; i--){
matrix[j][i]-=matrix[y][i]*matrix[j][x];
}
}

x++; y++;
}
return matrix;
}



/*
input.txt
4 5
1 2 3 7 55
1 3 2 4 76
3 2 1 6 43
4 6 5 3 34
*/

/*主程式*/
int main(){
int m,n,i,j;
FILE *in;
// 開啟檔案
in=fopen("input.txt","r");

// 讀取 m,n 值
fscanf(in,"%d\n",&m);
fscanf(in,"%d\n",&n);

// 利用 malloc 配置二維空間 。
double **mar= (double**) malloc(m * sizeof(double*));
for (i=0; i<m; i++){
mar[i] = (double*) malloc(n * sizeof(double));
}

// 讀取矩陣
for(i=0;i<m;i++){
for(j=0;j<n;j++){
fscanf(in,"%lf",&mar[i][j]);
}
}

// 高斯消去法
mar=matrix_rref(mar,m,n);

// 列印結果
for(i=0;i<m;i++){
for(j=0;j<n;j++){
printf("%.2lf ",mar[i][j]);
}
printf("\n");
}

_getch();

return 0;
}

2009-04-25 16:58

[LEX] 使用命令列參數開啟檔案


/*[flex] 的指令參數
* ( flex -FLi8 %f )
* -l 最大兼容性法則
* -i 不區分大小寫
* -f 產生不壓縮的完整表格,效率快,所需空間大
* -F 最佳效率與空間優化
* -L 在產生的程式碼中不加入 #line
* -7 使用 7 bit 掃瞄文字(預設)
* -8 使用 8 bit 掃瞄文字
*
* -+ 產生 C++ 掃瞄 Class
*
* -oOutputName 指定輸出檔案名稱
*
* -h 參數說明
* -V 版本顯示
* -T 顯示追蹤記錄
* */


/* [定義段落] */
%{
#include <stdio.h>

%}

/* 告知沒有自訂的 unput() */
%option nounput

/* 初始狀態 */
%s START
/* 多行註解狀態 */
%s COMMENTS

/* 換行符號 */
EN [\r\n]
/* 換行符號及空白字元 */
SP [ \t\r\n] //
/* 單引號字串 */
//STR1 (\'([^\'\r\n]|"\\\'")*\')
/* 雙引號字串 */
//STR2 (\"([^\"\r\n]|"\\\"")*\")


%% /* [規則段落] */

/* 多行註解模式 */
<COMMENTS>"*/"{SP}* { BEGIN START; }
<COMMENTS>.|{SP} ;

/* 初始模式 */
<START>"/*" { BEGIN COMMENTS; }
<START>"//".*{EN}+ ;
<START>. {fprintf(yyout,"%s",yytext);}


%% /* [自訂函數段落] */

/* 程式執行方式與檔案參數
* 程式.exe 文件1.txt 文件2.txt 文件3.txt
* 或使用文件拖放至程式上
* */
char **fileList;
unsigned currentFile = 0;
unsigned nFiles;

int main(int argc,char **argv){
// 沒有檔案
if(argc<2){
printf("沒有給予檔案參數");return 0;

}else{
// 取得檔案參數
fileList = argv+1;
nFiles = argc-1;

// 嘗試開啟第一個檔案
yywrap();
}

// 執行文字解析器
yylex();
/* 文字解析器會在檔案結束時
* 自動呼叫 yywrap() 開啟下一個檔案
* */

return 0;
}

/* 當沒自訂的 yywrap() 時
* 記得在前加上 "%option noyywrap"
* */
int yywrap(){
// 關閉上次開啟的檔案
if ((currentFile > 0) && (nFiles >= 1) && (currentFile <= nFiles)) {
// 關閉輸入與輸出的文件
fclose(yyin); fclose(yyout);

// 將暫存檔覆蓋原始輸入文件
remove(fileList[currentFile-1]);
rename("temp",fileList[currentFile-1]);
}

FILE *fileIn = NULL;
while ((currentFile < nFiles)) {
// 檢查副檔名
if(strstr(fileList[currentFile],".txt")!= NULL){
// 設定初始狀態
BEGIN START;
}else{
// 跳過不符合的檔案
continue;
}


// 嘗試開啟檔案
fileIn = fopen(fileList[currentFile++], "r");
if (fileIn != NULL) {
// 指定輸入與輸出的文件指標
yyin = fileIn;
yyout = fopen("temp","w");

// 成功開啟檔案跳出迴圈
break;
}
printf("無法開啟檔案: %s\n",fileList[currentFile-1]);
}
// 回傳狀態 ( 0:成功開啟 , 1:開啟失敗 )
return (fileIn ? 0 : 1);
}


相關連結:Yacc 与 Lex 快速入门
2009-04-25 03:21

[C語言] 快速排序法(quick sort)


#include<stdio.h>

/** quick_sort [快速排序法]
* @param {array} array
* @param {int} low
* @param {int} high
*/
int quick_sort(int *array,int low,int high) {
int pivot_point,pivot_item,i,j,temp;
// 指標交界結束排序
if(high<=low){return 1;}

// 紀錄樞紐值
pivot_item = array[low];
j=low;

// 尋找比樞紐小的數
for(i=low+1; i<=high; i++) {
// 跳過等於或大於的數
if(array[i]>=pivot_item){continue;}

j++;
// 交換 array[i] , array[j]
temp = array[i];
array[i] = array[j];
array[j] = temp;
}

// 將樞紐位址移到中間
pivot_point=j;
// 交換 array[low] , array[pivot_point]
temp = array[low];
array[low] = array[pivot_point];
array[pivot_point] = temp;

// 遞迴處理左側區段
quick_sort(array,low,pivot_point-1);
// 遞迴處理右側區段
quick_sort(array,pivot_point+1,high);

return 1;
}


/*主程式*/
int main(){
int a[]={12,42,54,3,5,32,61,24,31};

quick_sort(a,0,8);

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

_getch();
return 0;
}

2009-04-25 02:56

[C語言] 連結串列(link list)


/* link list (連結串列) */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

/* 定義結構型態 */
typedef struct link_node{
int data;
struct link_node *link;
} LINK_NODE;



/* 產生新節點 */
LINK_NODE *new_node(int data){
LINK_NODE *node;
node=(LINK_NODE *) malloc(sizeof(LINK_NODE));/*<stdlib.h>*/

// 記憶體不足
if(node == NULL){ return NULL;}

node->data=data;
node->link=NULL;
return node;
}


/* 加入新的資料於最後 */
LINK_NODE *push_node(LINK_NODE *list, int data){
/*產生新節點*/
LINK_NODE *node=new_node(data);

// 加入第一個新節點
if(list==NULL){
list=node;
}else{
LINK_NODE *p=list;
// 取得最後一個節點
while(p->link!=NULL){p=p->link;}
p->link=node;
}
return list;
}


/* 排序插入新節點 */
LINK_NODE *sort_insert(LINK_NODE *list,int data){
// 加入第一筆資料

// 產生新節點
LINK_NODE *node=new_node(data);
if(list==NULL){ list=node; return list; }

// 尋找大於資料(data)的位址
LINK_NODE *r=list,*q=list;
while(r!=NULL && r->data<data){ q=r; r=r->link; }

if(r==list){ // 首節點
node->link=list; list=node;
}else{ // 加入新節點於中間
node->link=q->link;
q->link=node;
}
return list;
}


/* 計算串列長度 */
int get_length(LINK_NODE *list){
LINK_NODE *p=list;
int count=0;
while(p!=NULL){
count++;
p=p->link;
}

return count;
}


/* 搜尋資料(data)的節點位子 */
LINK_NODE *search_node(LINK_NODE *list, int data){
LINK_NODE *p=list;
while(p!=NULL && p->data!=data){ p=p->link; }
return p ;
}


/* 印出所有串列的所有資料 */
int display(LINK_NODE *list){
LINK_NODE *p=list;
while(p!=NULL){
printf("%d\n",p->data);/*<stdio.h>*/
p=p->link;
}
return 1;
}




/*主程式*/
int main(){
LINK_NODE *list=NULL;

list=sort_insert(list,4);
list=sort_insert(list,2);
list=sort_insert(list,7);
list=sort_insert(list,9);
list=sort_insert(list,14);
display(list);

printf("--------------------------\n");

list=push_node(list,4);
list=push_node(list,2);
list=push_node(list,7);
list=push_node(list,9);
list=push_node(list,14);
display(list);

_getch();
return 0;
}

2009-04-25 01:47

[C語言] 字串取代(str_replace)

strlen , strcpy , strstr , strcat , malloc

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

/* str_replace [字串取代]
* @param {char*} source 原始的文字
* @param {char*} find 搜尋的文字
* @param {char*} rep 替換的文字
* */
char *str_replace (char *source, char *find, char *rep){
// 搜尋文字的長度
int find_L=strlen(find);
// 替換文字的長度
int rep_L=strlen(rep);
// 結果文字的長度
int length=strlen(source)+1;
// 定位偏移量
int gap=0;

// 建立結果文字,並複製文字
char *result = (char*)malloc(sizeof(char) * length);
strcpy(result, source);

// 尚未被取代的字串
char *former=source;
// 搜尋文字出現的起始位址指標
char *location= strstr(former, find);

// 漸進搜尋欲替換的文字
while(location!=NULL){
// 增加定位偏移量
gap+=(location - former);
// 將結束符號定在搜尋到的位址上
result[gap]='\0';

// 計算新的長度
length+=(rep_L-find_L);
// 變更記憶體空間
result = (char*)realloc(result, length * sizeof(char));
// 替換的文字串接在結果後面
strcat(result, rep);
// 更新定位偏移量
gap+=rep_L;

// 更新尚未被取代的字串的位址
former=location+find_L;
// 將尚未被取代的文字串接在結果後面
strcat(result, former);

// 搜尋文字出現的起始位址指標
location= strstr(former, find);
}

return result;

}


int main(){
char* str1 = "this is a string of characters";
char* str2 = str_replace(str1, "is","FFF");

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

_getch();
return 0;
}



參考來源:
Standard C String and Character [C++ Reference]