2013年12月3日 星期二

linux C心得

linux版本 centos 6
如何開始?
http://linux.vbird.org/linux_basic/0520source_code_and_tarball.php#simple_ex_hello

正在試:
http://www.cyberciti.biz/tips/linux-unix-connect-mysql-c-api-program.html
http://www.cyberciti.biz/files/mysql-c-api.c.txt
要改寫成 #include <mysql/mysql.h>

執行a.out, 出現錯誤:
mytable.c:6:19: 錯誤:mysql.h:沒有此一檔案或目錄
mytable.c: In function 「main」:
mytable.c:10: 錯誤:「MYSQL」 未宣告 (在此函式內第一次使用)
mytable.c:10: 錯誤:(即使在一個函式內多次出現,每個未宣告的識別碼在其
mytable.c:10: 錯誤:所在的函式內只報告一次。)
mytable.c:10: 錯誤:「conn」 未宣告 (在此函式內第一次使用)
mytable.c:11: 錯誤:「MYSQL_RES」 未宣告 (在此函式內第一次使用)
mytable.c:11: 錯誤:「res」 未宣告 (在此函式內第一次使用)
mytable.c:12: 錯誤:「MYSQL_ROW」 未宣告 (在此函式內第一次使用)
mytable.c:12: 錯誤:expected 「;」 before 「row」
mytable.c:25: 警告:隱含宣告與內建函式 「exit」 不相容
mytable.c:31: 警告:隱含宣告與內建函式 「exit」 不相容
mytable.c:38: 錯誤:「row」 未宣告 (在此函式內第一次使用)


http://stackoverflow.com/questions/14604228/mysql-h-file-cant-be-found
The mysql.h file from the libmysqlclient-dev Ubuntu package is located at /usr/include/mysql/mysql.h.

在centos安裝libmysqlclient-dev方法
https://www.centos.org/forums/viewtopic.php?t=29620
# yum list \*mysql\* | grep dev

# yum install mysql-devel.i686
安裝成功 -
# sudo yum install mysql-server mysql mysql-dev
...
Setting up Install Process
Package mysql-server-5.1.71-1.el6.i686 already installed and latest version
Package mysql-5.1.71-1.el6.i686 already installed and latest version
Package mysql-devel-5.1.71-1.el6.i686 already installed and latest version
Nothing to do
( 有裝成功有這隻檔案 /usr/include/mysql/mysql.h )

錯誤:
# gcc mytable.c
/tmp/ccaOFT1h.o: In function `main':
mytable.c:(.text+0x3d): undefined reference to `mysql_init'
mytable.c:(.text+0x91): undefined reference to `mysql_real_connect'
mytable.c:(.text+0xa1): undefined reference to `mysql_error'
mytable.c:(.text+0xe8): undefined reference to `mysql_query'
mytable.c:(.text+0xf8): undefined reference to `mysql_error'
mytable.c:(.text+0x137): undefined reference to `mysql_use_result'
mytable.c:(.text+0x16c): undefined reference to `mysql_fetch_row'
mytable.c:(.text+0x183): undefined reference to `mysql_free_result'
mytable.c:(.text+0x18f): undefined reference to `mysql_close'
collect2: ld 回傳 1
http://lyxxiang.blog.163.com/blog/static/22846192011615105821150/
解法:
# gcc -o mytable $(mysql_config --cflags) mytable.c $(mysql_config --libs)

錯誤:
mytable.c:27: 警告:隱含宣告與內建函式 「exit」 不相容
解法:
加入 #include <stdlib.h>

要怎麼傳入參數? ( # mytable note add "message" )
http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt
或用for
http://stackoverflow.com/questions/498320/pass-arguments-into-c-program-from-command-line
int main(int argc, char *argv[])
{
    int i = 0;
    for (i = 0; i < argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
    return 0;
}

美化縮排:
使用vim  gg=G

字串連結
http://stackoverflow.com/questions/308695/c-string-concatenation
char * sql = "INSERT INTO `mytable`.`note` (\
`message` ,\
)\
VALUES (\
'%s'
);";
char sql_buf[256];
snprintf(sql_buf, sizeof sql_buf, sql, message);
printf("sql_buf:%s\n", sql_buf);

字串比較:
http://www.programmingsimplified.com/c-program-compare-two-strings
if( strcmp(a,b) == 0 )
   printf("Entered strings are equal.\n");
else
   printf("Entered strings are not equal.\n");

寫Makefile:
http://kevincrazy.pixnet.net/blog/post/29780477-makefile%E7%B0%A1%E6%98%93%E6%95%99%E5%AD%B8...
# it is a test
all:hello.c
gcc hello.c -o hello
clean:
rm -f hello

錯誤:
Makefile:4: *** missing separator.  Stop.
http://www.wretch.cc/blog/awaysu/24890447
解法: 縮排使用tab而非空白

Makefile裡面錯誤再現
# make
gcc -o mytable  mytable.c
/tmp/ccxINA1O.o: In function `main':
mytable.c:(.text+0x85): undefined reference to `mysql_init'
原因:裡面看不懂 $(mysql_config --cflags) 和 $(mysql_config --libs)
解法:
在命令列中輸入mysql_config --cflags 和 mysql_config --libs 把值印出來
直接寫死在Makefile裡面

讀取conf檔
http://jax-work-archive.blogspot.tw/2011/03/c_28.html
錯誤:
test_config.c:13: 錯誤:expected 「=」, 「,」, 「;」, 「asm」 or 「__attribute__」 before 「readConfig」
解法:
http://stackoverflow.com/questions/13274230/how-to-work-with-boolean-function-in-c
新增 #include <stdbool.h>
bool readConfig()要寫在main()前面

將char * 轉化為數字
http://stackoverflow.com/questions/9610895/how-do-you-cast-a-char-to-an-int-or-a-double-in-c
int i = atoi(c);
/* int    note_id = atoi(argv[3]); */

C語言物件寫法
http://www.bolthole.com/OO-C-programming.html
錯誤:
FooOBJ.c: In function 「newFooOBJ」:
FooOBJ.c:20:21: 警告: 隱含宣告與內建函式 「malloc」 不相容 [enabled by default]
FooOBJ.c:21:2: 警告: 隱含宣告與內建函式 「bzero」 不相容 [enabled by default]
FooOBJ.c: In function 「deleteFooOBJ」:
FooOBJ.c:53:2: 警告: 隱含宣告與內建函式 「free」 不相容 [enabled by default]
解法:
bzero => 新增 #include <string.h>
malloc、free => 新增 #include <malloc.h>
編譯:
$ gcc test.c FooOBJ.c
執行:
$ ./a.out

透過malloc()所分配出來的空間必須由使用者呼叫free()才能歸還給系統。初學者常犯的錯誤之一,就是忘了用free()歸還空間,這會造成程式佔用太多記憶體,此現象稱為memory leakage。相反的,如果空間已用free()歸還了,卻還試著去使用那塊記憶體,則會發生Segmentation Fault (core dumped)的錯誤。

如果將mysql的操作移到FooOBJ.c後,$(mysql_config --libs)要移到FooOBJ.c後面
gcc -o mytable $(mysql_config --cflags) mytable.c FooOBJ.c $(mysql_config --libs)

把struct當參數傳入function (類似以物件方式傳入函數中)
http://stackoverflow.com/questions/10370047/passing-struct-to-function
void addStudent(struct student person) {

}
struct相關用法:
http://programming.im.ncnu.edu.tw/Chapter13.htm
http://openhome.cc/Gossip/CGossip/StructABC.html

getopt
http://people.cs.nctu.edu.tw/~yslin/library/linuxc/main.htm
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html#Example-of-Getopt
傳入多個字串的參數
http://stackoverflow.com/questions/1973742/how-to-get-a-value-from-optarg
c = getopt(argc, argv, "i:p:") //一個參數後面就接一個冒號(:)

在ubuntu上安裝ansi c 的函數手冊(man)
http://superuser.com/questions/40609/how-to-install-man-pages-for-c-standard-library-functions-in-ubuntu
$ apt-get install manpages-dev manpages-posix-dev
問題:
$ man getopt
結果出現的是User Commands的文件
變成要使用 $ man --all getopt 一頁一頁看後面這兩種文件
Linux Programmer's Manual => getopt(3)
POSIX Programmer's Manual => getopt(3posix)
有方法直接看Linux Programmer's Manual裡面的getopt man page嗎?
答:
$ man 3 getopt
加-w可以找到該 manpage 的路徑
加-f列出清單

ubunut搜尋有哪些套件可以裝
http://www.techiecorner.com/320/how-to-use-apt-to-list-available-packages/
# this will list all packages available thru apt-get
$ apt-cache pkgnames

# this will only return you the relevant result
$ apt-cache search 'your search term here'

使用getopt_long 讀取參數
http://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html

留言板參考:
http://yiyingloveart.blogspot.tw/2012/01/php.html


沒有留言:

張貼留言