C 语言的运算顺序问题 - 看看代码并实际运行一下,结果能明白吗?

31 views
Skip to first unread message

周立发

unread,
Sep 1, 2009, 2:03:16 AM9/1/09
to china-li...@googlegroups.com
代码如下:
/*************分界符开始***********************/
#include <stdio.h>

int main(void)
{
    int i = 2;
    printf("%d %d\n", i++, i++);
    printf("%d\n", i++ * i++);
    printf("%d\n", i);
    return 0;
}
/*************分界符结束***********************/

在我的Intel Pentium III机器Ubuntu 8.04.3系统上运行结果如下:
/*************分界符开始***********************/
3 2
16
6
/*************分界符结束***********************/


Jacky

unread,
Sep 1, 2009, 2:08:24 AM9/1/09
to China Linux Fans
还有这个:
/*************分界符开始***********************/
#include <stdio.h>
#include <string.h>
void func(char *str)
{
printf("sizeof(str)=%d\n", sizeof(str));
printf("sizeof(*str)=%d\n", sizeof(*str));
printf("strlen(str)=%d\n", strlen(str));

}

int main(void)
{
int b[] = { 1, 2, 3, 4, 5, 6 };
char a[] = "123456789";
printf("sizeof(a)=%d\n", sizeof(a));
printf("sizeof(b)=%d\n", sizeof(b));
func(a);
return 0;

}
/*************分界符结束***********************/
看到电脑上一些临时代码,小、也没多大技术含量,本想直接删除,想想还是直接贴上来或许可以分享一下

Jacky

unread,
Sep 1, 2009, 2:13:58 AM9/1/09
to China Linux Fans
这个其它man -a writev就看到了,但可能很多人没用过吧,一次读写多个buffer的函数:
/*************分界符开始***********************/
#include <string.h>
#include <unistd.h>
#include <sys/uio.h>

int main(void)
{
char *str0 = "hello ";
char *str1 = "world\n";
struct iovec iov[2];
ssize_t nwritten;

iov[0].iov_base = str0;
iov[0].iov_len = strlen(str0);
iov[1].iov_base = str1;
iov[1].iov_len = strlen(str1);

nwritten = writev(STDOUT_FILENO, iov, 2);
return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 1, 2009, 2:18:34 AM9/1/09
to China Linux Fans
这份代码能运行成功吗?数组y的下标是0,申明这样的数组在实际代码中很多的:
/*************分界符开始***********************/
#include <stdio.h>

int main(void)
{
struct x {
int a;
char b;
short c;
};
struct x y[0];

printf("sizeof(y):%d\n", sizeof(y));
y[0].a = 1;

return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 1, 2009, 2:20:24 AM9/1/09
to China Linux Fans
结构体是可以直接赋值的,但很多人怀疑,看看这个代码的运行结果吧:
/*************分界符开始***********************/
#include <stdio.h>
struct x {
int a;
int b;
} x, y;

int main(int argc, char **argv)
{
x.a = 11;
x.b = 2;

y = x;

printf("y.a:%d y.b:%d\n", y.a, y.b);
return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 1, 2009, 2:27:36 AM9/1/09
to China Linux Fans
通过结构体成员的地址找到结构体变量的地址,这个宏在Linux内核代码里用到很多:
/*************分界符开始***********************/
#include <stdio.h>

#define size_t int

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

int main(void)
{
struct x {
char a;
int b;
short c;
} y;
printf("%p\n", &y);
printf("%p\n", &y.a);
printf("%p\n", &y.b);
printf("%p\n", &y.c);
printf("%p\n", container_of(&y.c, struct x, c));
return 0;
}
/*************分界符结束***********************/

上面的结构体变量y,如果知道了y.c就能找到y的地址

Jacky

unread,
Sep 1, 2009, 2:32:27 AM9/1/09
to China Linux Fans
调试时用到的宏:
/*************分界符开始***********************/
#include <stdio.h>
#include <errno.h>
#include <string.h>

#define MyPrt(fmt, args...) {\
printf("%s(%d)-%s:" fmt "--Errno:%d, errMsg:%s\n", __FILE__,
__LINE__, __FUNCTION__, ##args, errno, strerror(errno));\
}

void MyFunc(int ac)
{
MyPrt("%d", ac);
}

int main(int argc, char **argv)
{
MyPrt("%s", argv[0]);
MyFunc(argc);
return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 1, 2009, 2:35:03 AM9/1/09
to China Linux Fans
找出两个已经排序的文件中内容相同的行:
/*************分界符开始***********************/
#include <stdio.h>

int main(int argc, char **argv)
{
int linenuma, linenumb, linelena, linelenb, cmpret;
if (reta == -1)
break;

FILE *fda, *fdb;
char *linea = 0, *lineb = 0;
ssize_t reta, retb;

fda = fopen(argv[1],);
fdb = fopen(argv[2],);
linenuma = 0;
linenumb = 0;
cmpret = 0;
while (!feof(fda) && !feof(fdb)) {
if (cmpret <= 0) {
if (linea)
free(linea);
reta = getline(&linea, &linelena, fda);
if ((reta == -1) && (cmpret != 0))
break;
linenuma++;
}
if (cmpret >= 0) {
if (lineb)
free(lineb);
retb = getline(&lineb, &linelenb, fdb);
if ((retb == -1) && (cmpret != 0))
break;
linenumb++;
}
cmpret = strcmp(linea, lineb);
if (cmpret == 0) {
printf("A:%d == B:%d\n", linenuma, linenumb);
}
}
fclose(fda);
fclose(fdb);
}
/*************分界符结束***********************/

zzzz88

unread,
Sep 1, 2009, 9:29:52 PM9/1/09
to china-li...@googlegroups.com

我就不明白出这样的题目 printf("%d\n", i++ * i++); ,有什么意义,平常你写
代码还真写成这样?

zzz...@yahoo.cn

-----------------------------------------
Thunderbird + Gnupg + Enigmail = PGP/MIME

__________________________________________________
�Ͽ�ע���Ż���������������?
http://cn.mail.yahoo.com

Jacky

unread,
Sep 1, 2009, 10:39:03 PM9/1/09
to China Linux Fans
这种代码唯一的实际意义在于:招聘时难倒几个人。
实际工程中不可能写的

Jacky

unread,
Sep 4, 2009, 11:36:46 PM9/4/09
to China Linux Fans
这是一个简单的HTTP Server示例,编译后运行,打开浏览器访问http://127.0.0.1:1234即可看到效果。
当然,如果你在程序运行的目录里有个文件是index.html,那么访问http://127.0.0.1:1234/index.html即可。

/*************分界符开始***********************/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/wait.h>
#include <sys/sendfile.h>

#define MAXLINE 2048
#define MAX_URI_LEN 2048
static int GetOneLine(int fd, char **buf, const int maxlen)
{
char ch = 0, lastch = 0;
int ret, i, j;
*buf = (char *) malloc(maxlen);
if (*buf == 0)
return -1;
memset(*buf, 0, maxlen);
i = 0;

for (j = 0; j < maxlen; j++) {
ret = recv(fd, &ch, 1, 0);
if (ret == 0)
return (j ? (j - 1) : 0);
if (ret == -1)
return (j ? (j - 1) : 0);
if ((ch == '\n') && (lastch == '\r')) {
*(*buf + i - 1) = 0;
return (j - 1);
}
if (ret == 1) {
*(*buf + i) = ch;
}
i++;
lastch = ch;
}
return maxlen;
}

static int handleRequest(int fd)
{
char *line = 0;
char method[8] = "";
char uri[MAX_URI_LEN] = "";
char httpversion[16] = "";
char bound[1024] = "";
char head[256] = "";
char *p;
int ret = -1, status;
struct stat fs;
ret = GetOneLine(fd, &line, MAXLINE); /* Get first line, request-
command-line */
printf("ret:%d, buf:'%s'\n", ret, line);
sscanf(line, "%s %s %s", method, uri, httpversion);
printf("method:%s uri:%s v:%s\n", method, uri, httpversion);
free(line);
while ((ret = GetOneLine(fd, &line, MAXLINE)) > 0) { /* Get header
and blank line */
printf("ret=%d, line:'%s'\n", ret, line);
p = strstr(line, "boundary=");
if (p) {
strcpy(bound, p + 9);
printf("Boundary is:'%s'\n", bound);
}
free(line);
}
if (ret >= 0)
free(line); /* Free blank line */

if (strlen(bound) > 0) {
ret = GetOneLine(fd, &line, MAXLINE);
if ((line[0] == '-') && (line[1] == '-') && !strcmp(line + 2, bound))
{
printf("Got boundary!\n");
free(line);
ret = GetOneLine(fd, &line, MAXLINE);
p = strstr(line, "filename=\"");
if (p && p[10] != '"') {
char *xx;
char filename[256] = "";
int f_fd;
xx = strchr(p + 10, '"');
if (xx) {
memcpy(filename, p + 10, xx - p - 10);
printf("filename is:'%s'\n", filename);
}
free(line);
ret = GetOneLine(fd, &line, MAXLINE);
free(line);
ret = GetOneLine(fd, &line, MAXLINE);
free(line);
f_fd =
open(filename, O_RDWR | O_CREAT | O_APPEND,
S_IRWXU | S_IRWXG | S_IRWXO);
if (f_fd == -1)
printf("Create file '%s' Error!\n", filename);
else {
char r_ch_b;
char *b_end_flag = 0;
int b_e_len, t_b_i = 0;
b_e_len = strlen(bound) + 8;
b_end_flag = (char *) malloc(b_e_len);
memset(b_end_flag, 0, b_e_len);
b_end_flag[0] = '\r';
b_end_flag[1] = '\n';
b_end_flag[2] = '-';
b_end_flag[3] = '-';
strcpy(b_end_flag + 4, bound);
t_b_i = 0;
while (1) {
ret = recv(fd, &r_ch_b, 1, 0);
if (ret > 0) {
if (r_ch_b == b_end_flag[t_b_i]) {
t_b_i++;
if (t_b_i == strlen(b_end_flag))
break;
continue;
} else {
if (t_b_i > 0)
write(f_fd, b_end_flag, t_b_i);
t_b_i = 0;
write(f_fd, &r_ch_b, 1);
}
} else
break;
}
close(f_fd);
}
} else
free(line);
} else {
printf("Error!\n");
free(line);
}
} else {
#ifdef SIMPLE_OUT
if (!fork()) {
close(1);
dup2(fd, 1);
system("cat upload.html");
exit(0);
}
waitpid(-1, &status, 0);
#endif /* End of SIMPLE_OUT */
memset(head, 0, sizeof(head));
printf("filename:%s\n", uri);
if ((strlen(uri) < 2) || (uri[0] != '/') || (stat(uri + 1, &fs))) {
sprintf(head,
"HTTP/1.1 404 Not Found\r\nContent-Length:111\r\n\r
\n<html><body>The file you requested doesnot exist!</br>Please input a
filename or a directory path</body></html>");
send(fd, head, strlen(head), 0);
} else {
if (S_ISREG(fs.st_mode)) { /* File */
int in_fd;
off_t inf_of_t = 0;
sprintf(head, "HTTP/1.1 200 OK\r\nContent-Length:%d\r\n\r\n",
fs.st_size);
send(fd, head, strlen(head), 0);
in_fd = open(uri + 1, O_RDONLY);
sendfile(fd, in_fd, &inf_of_t, fs.st_size);
close(in_fd);
} else if (S_ISDIR(fs.st_mode)) { /* Directory */
int componentsNum = 0, i, dirContentLen = 0;
char *allDirContent = 0, oneFileBufLine[128] = "";
struct dirent **namelist;
componentsNum = scandir(uri + 1, &namelist, 0, alphasort);
allDirContent = (char *) malloc(componentsNum * 128);
memset(allDirContent, 0, componentsNum * 128);
for (i = 0; i < componentsNum; i++) {
memset(oneFileBufLine, 0, sizeof(oneFileBufLine));
sprintf(oneFileBufLine, "<a href=\"./%s/%s\">%s</a><br>",
uri + 1, namelist[i]->d_name, namelist[i]->d_name);
strcpy(allDirContent + strlen(allDirContent),
oneFileBufLine);
free(namelist[i]);
}
free(namelist);
sprintf(head,
"HTTP/1.1 200 OK\r\nContent-Length:%d\r\n\r\n<html><body>",
strlen(allDirContent) + 26);
send(fd, head, strlen(head), 0);
send(fd, allDirContent, strlen(allDirContent), 0);
send(fd, "</body></html>", 14, 0);
free(allDirContent);
}
}
close(fd);
return 0;
}
}

int main(int argc, char **argv)
{
int server_sockfd, new_server_sockfd;
socklen_t server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
char buffer1[10];
char buffer[1024];
char *buf = buffer;
int ret;
int retu;
int nfds;
int i, j = 0, k, m, n = 0, flag;
int offset;
int fileret, readlen;
int opt = 1;
char *s1 = "filename";
DIR *dirret;
char postbuffer[1024];
char buffertmp[2048];
int newfd;
char *cmp = "POST";
struct dirent *readret;
struct stat fstat;
struct epoll_event ev, events[10];

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = 0;
server_address.sin_port = htons(1234);
client_len = server_len = sizeof(server_address);

setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof
(opt));

bind(server_sockfd, (struct sockaddr *) &server_address,
server_len);

listen(server_sockfd, 5);

ret = epoll_create(10);

if (fcntl(server_sockfd, F_SETFL, O_NONBLOCK) == -1)
return 0;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = server_sockfd;
epoll_ctl(ret, EPOLL_CTL_ADD, server_sockfd, &ev);

while (1) {
nfds = epoll_wait(ret, events, 10, -1);
for (i = 0; i < nfds; i++) {
if (events[i].data.fd == server_sockfd) {
new_server_sockfd =
accept(server_sockfd, (struct sockaddr *) &client_address,
&client_len);
if (fcntl(new_server_sockfd, F_SETFL, O_NONBLOCK) == -1)
return 0;
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = new_server_sockfd;
epoll_ctl(ret, EPOLL_CTL_ADD, new_server_sockfd, &ev);
} else {
retu = handleRequest(events[i].data.fd);
}
}
}
return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 4, 2009, 11:42:48 PM9/4/09
to China Linux Fans
一个fdopen使用示例:
fdopen是C标准库stdio.h提供的一个函数,可以把一个Unix C标准库unistd.h函数open得到的一个file
descriptor转换成一个FILE *指针,可以用两套库函数同时访问同一个文件。
但要注意,正如这个例子所演示的:共享了文件指针的,所以一种方法操作了文件,必然导致另一个方法操作之后的内容。
/*************分界符开始***********************/
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{

int fd;
FILE *fp;
char chb;
fd = open(argv[1], O_RDONLY);
if (fd == -1)
return -1;
fp = fdopen(fd, "r");
if (fp == NULL)
return -2;
while (fread(&chb, 1, 1, fp) == 1) {
printf("%d---ch:%c\n", __LINE__, chb);
}
if (read(fd, &chb, 1) == 1)
printf("%d---ch:%c\n", __LINE__, chb);
else
printf("%d---nothing read!\n", __LINE__);
fclose(fp);
close(fd);
return 0;
}
/*************分界符结束***********************/

Jacky

unread,
Sep 4, 2009, 11:47:08 PM9/4/09
to China Linux Fans
非常短的代码,对于理解进程(Process)和程序(Program)的差别非常有帮助。
/*************分界符开始***********************/
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{

printf("%s %d\n", argv[0], remove(argv[0]));
return sleep(5);
}
/*************分界符结束***********************/

argv[0]是表示运行的程序本身吧?
remove返回值0是表示remove成功了吧?
为什么可以成功呢?因为Process和Program的差别。

JackyZhou

unread,
Oct 13, 2009, 10:18:40 AM10/13/09
to China Linux Fans
找出100以内符合勾股定理的整数组合:
/*************分界符开始***********************/
#include <stdio.h>
#include <math.h>

#define MAX_NUM 100

int main(void)
{
int i, j;
float k;
for (i = 1; i < MAX_NUM; i++)
for (j = i + 1; j < MAX_NUM; j++)
if (i * i + j * j <= MAX_NUM * MAX_NUM) {
k = sqrt(i * i + j * j);
if ((k == (int) k) && (4 * i == 3 * j) && (5 * j == 4 * k))
printf("%03d^2+%03d^2=%03.0f^2\n", i, j, k);
}

return 0;
}
/*************分界符结束***********************/
好象是好久以前一个朋友去一家公司面试遇到的题目,当时帮他写的

JackyZhou

unread,
Oct 13, 2009, 10:24:22 AM10/13/09
to China Linux Fans
把字符串反序输出:
/*************源代码reverseString.c分界符开始***********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>

#define FreeP(p) {\
free(p);\
p=0;\
}

static int reverseItAllTrip(const char *src, char **dst)
{
int len, i;
char *p = 0;
len = strlen(src);
*dst = (char *) malloc(len + 1);
memset(*dst, 0, len + 1);
p = src;
i = len;
while (p && *p) {
*(*dst + i - 1) = *p;
i--;
p++;
}
return 0;
}

static int reverseItHalfTrip(const char *src, char **dst)
{
int len, i;
char ch;
len = strlen(src);
*dst = (char *) malloc(len + 1);
memset(*dst, 0, len + 1);
for (i = 0; i < (len / 2); i++) {
ch = src[i];
*(*dst + i) = src[len - i - 1];
*(*dst + len - i - 1) = ch;
}
if (len % 2)
*(*dst + len - i - 1) = src[len - i - 1];
return 0;
}

#ifdef DEBUG
#define MAX_STR_LEN 65
#else
#ifdef DEBUG_SIZE
#define MAX_STR_LEN (DEBUG_SIZE)
#else
#define MAX_STR_LEN (1024*1024*20)
#endif
#endif

int main(int argc, char **argv)
{
struct timeval tvStart, tvStop;
int i;
char *src = 0, *dst = 0;
src = (char *) malloc(MAX_STR_LEN + 1);
if (src == NULL) {
printf("malloc for src buffer error!\n");
exit(1);
}
for (i = 0; i < MAX_STR_LEN; i++) {
src[i] = i % 26 + 65;
}
#ifdef DEBUG
printf("src:'%s'\n", src);
#endif
gettimeofday(&tvStart, NULL);
reverseItAllTrip(src, &dst);
gettimeofday(&tvStop, NULL);
#ifdef DEBUG
printf("src:'%s', dst:'%s'\n", src, dst);
#endif
printf("TimeFrom:'%d:%d', TimeTo:'%d:%d'\tAllTrip Used:%d\n",
tvStart.tv_sec, tvStart.tv_usec, tvStop.tv_sec, tvStop.tv_usec,
(tvStop.tv_sec - tvStart.tv_sec) * 1000000 + (tvStop.tv_usec -
tvStart.tv_usec));
FreeP(dst);

gettimeofday(&tvStart, NULL);
reverseItHalfTrip(src, &dst);
gettimeofday(&tvStop, NULL);
#ifdef DEBUG
printf("src:'%s', dst:'%s'\n", src, dst);
#endif
printf("TimeFrom:'%d:%d', TimeTo:'%d:%d'\tHalfTrip Used:%d\n",
tvStart.tv_sec, tvStart.tv_usec, tvStop.tv_sec, tvStop.tv_usec,
(tvStop.tv_sec - tvStart.tv_sec) * 1000000 + (tvStop.tv_usec -
tvStart.tv_usec));
FreeP(src);
FreeP(dst);
return 0;

}
/*************源代码reverseString.c分界符结束***********************/
分别用不同的DEBUG_SIZE编译本程序看看运行结果,上述两种把字符串反序输出的方法,哪种效率更高呢?
gcc -DDEBUG_SIZE=65535 reverseString.c
gcc -DDEBUG_SIZE=1048576 reverseString.c
gcc -DDEBUG_SIZE=10485760 reverseString.c
gcc -DDEBUG_SIZE=20971520 reverseString.c
gcc -DDEBUG_SIZE=41943040 reverseString.c

JackyZhou

unread,
Oct 13, 2009, 10:31:14 AM10/13/09
to China Linux Fans
程序参数使用方法:
/*************源代码getopt.c分界符开始***********************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
int xflags, flags, opt;
int nsecs, tfnd, i;
for (i = 0; i < argc; i++)
printf("参数%d:%s\n", i + 1, argv[i]);

nsecs = 0;
tfnd = 0;
flags = 0;
while ((opt = getopt(argc, argv, "nt:x")) != -1) {
switch (opt) {
case 'x':
xflags = 1;
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", argv[0]);
exit(EXIT_FAILURE);
}
}

printf("x:%d flags=%d; tfnd=%d; optind=%d\n", xflags, flags, tfnd,
optind);

if (optind >= argc) {
fprintf(stderr, "Expected argument after options\n");
exit(EXIT_FAILURE);
}

printf("name argument = %s\n", argv[optind]);

/* Other code omitted */

exit(EXIT_SUCCESS);
}
/*************源代码getopt.c分界符结束***********************/
长格式参数使用方法:
/*************源代码get_long_opt.c分界符开始***********************/
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>

int main(int argc, char **argv)
{
int c;
int digit_optind = 0;

while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 1, 0, 'c'},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};

c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;

switch (c) {
case 0:
printf("llll-option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;

case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;

case 'a':
printf("a option a\n");
break;

case 'b':
printf("option b\n");
break;

case 'c':
printf("option c with value '%s'\n", optarg);
break;

case 'd':
printf("option d with value '%s'\n", optarg);
break;

case '?':
break;

default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}

if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}

exit(EXIT_SUCCESS);
}
/*************源代码get_long_opt.c分界符结束***********************/

JackyZhou

unread,
Oct 13, 2009, 10:58:37 AM10/13/09
to China Linux Fans
自己写的一个代替strchr的函数:
/*************源代码x_strchr.c分界符开始***********************/
#include <stdio.h>

char *x_strchr(char *s, int c)
{
char *p = s;
while (p && *p) {
if (*p == c)
return p;
p++;
}
return NULL;
}

int main(int argc, char **argv)
{
char *s = "abc 123";
char *p;
p = x_strchr(s, '1');
printf("p:%s\n", p);
return 0;
}
/*************源代码x_strchr.c分界符结束***********************/

JackyZhou

unread,
Oct 13, 2009, 11:06:02 AM10/13/09
to China Linux Fans
一个execl函数使用的例子,以执行ls命令为例,函数的第一个参数是要执行的程序的绝对路径,第二个参数是要执行的程序的名称即ls,相当于c程序
中的参数argv[0],之后的参数是该命令的参数,最后一个必须是(char *)NULL:
/*************源代码execl.c分界符开始***********************/
#include <unistd.h>

int main(int argc, char **argv)
{

execl("/bin/ls", "ls", "-a", (char *) NULL);
return 0;
}
/*************源代码execl.c分界符结束***********************/

如果命令ls没有参数可以写成:
/*************源代码execl.c分界符开始***********************/
#include <unistd.h>

int main(int argc, char **argv)
{

execl("/bin/ls", "ls", (char *) NULL);
return 0;
}
/*************源代码execl.c分界符结束***********************/

JackyZhou

unread,
Oct 13, 2009, 11:09:57 AM10/13/09
to China Linux Fans
一个目录操作示例:
/*************源代码lsdir.c分界符开始***********************/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char **argv)
{
DIR *dp;
struct dirent *df;
dp = opendir(argv[1]);
while ((df = readdir(dp))) {
if (df->d_type & DT_REG)
printf("file:");
else
printf("dir:");
printf("%s\n", df->d_name);
}
closedir(dp);
return 0;
}
/*************源代码lsdir.c分界符结束***********************/

JackyZhou

unread,
Oct 14, 2009, 4:15:16 AM10/14/09
to China Linux Fans
一个租房时找房子的程序,运行firefox访问http://shenghuo.google.cn里的租房网页。

/*************源代码rent.c分界符开始***********************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
int j, len, plow, phigh, slow, shigh;
char *addr, *city, *dist, buf[1024] = "", tmp[1024] = "";

if (argc < 4) {
printf
("请输入城市名称、区域名称、地点名称[、价格下限、价格上限、面积下限、面积上限]\n");
return -1;
}
addr = argv[3];
dist = argv[2];
city = argv[1];

strcpy
(buf,
"\nhttp://shenghuo.google.cn/shenghuo/search?a_n0=%E6%88%BF
%E5%B1%8B&a_n1=%E5%9F%8E%E5%B8%82&a_y1=1&a_o1=0&a_v1=");
len = strlen(city);
for (j = 0; j < len; j++) {
sprintf(tmp, "%%%02X", (unsigned char) city[j]);
strcat(buf, tmp);
memset(tmp, 0, sizeof(tmp));
}

strcat
(buf,
"&a_n2=%E7%B1%BB%E5%88%AB&a_y2=1&a_o2=0&a_v2=%E5%87%BA
%E7%A7%9F&q=");
len = strlen(dist);
for (j = 0; j < len; j++) {
sprintf(tmp, "%%%02X", (unsigned char) dist[j]);
strcat(buf, tmp);
memset(tmp, 0, sizeof(tmp));
}

strcat
(buf,
"&ct=h&cd=1#a_y0%3D9%26a_n0%3D!5E6!588!5BF!5E5!5B1!58B%26q%3D");
len = strlen(addr);
for (j = 0; j < len; j++) {
sprintf(tmp, "!5%02X", (unsigned char) addr[j]);
strcat(buf, tmp);
memset(tmp, 0, sizeof(tmp));
}
if ((argc > 4) && argv[4])
plow = atoi(argv[4]);
else
plow = 1500;
if ((argc > 5) && argv[5])
phigh = atoi(argv[5]);
else
phigh = 2200;
if ((argc > 6) && argv[6])
slow = atoi(argv[6]);
else
slow = 30;
if ((argc > 7) && argv[7])
shigh = atoi(argv[7]);
else
shigh = 70;

sprintf
(tmp,
"%%26view%%3DTable%%26a_n1%%3D!5E5!59F!58E!5E5!5B8!582%%26a_y1%%3D1%
%26a_o1%%3D0%%26a_v1%%3D!5E4!5B8!58A!5E6!5B5!5B7%%26a_n2%%3D!5E4!5BB!
5B7!5E6!5A0!5BC%%26a_y2%%3D8%%26a_o2%%3D3%%26a_f2%%3D%d%%26a_t2%%3D%d%
%26a_u2%%3Dcny%%26a_n3%%3D!5E5!59C!5B0!5E5!58C!5BA%%26a_y3%%3D1%
%26a_o3%%3D0%%26a_v3%%3D!5E5!5BE!590!5E6!5B1!587!5E5!58C!5BA%%26a_n4%
%3D!5E9!59D!5A2!5E7!5A7!5AF%%26a_y4%%3D2%%26a_o4%%3D3%%26a_f4%%3D%d%
%26a_t4%%3D%d%%26a_n5%%3D!5E6!59D!5A5!5E6!5BA!590%%26a_y5%%3D1%%26a_o5%
%3D0%%26a_v5%%3D!5E4!5B8!5AA!5E4!5BA!5BA%%26a_n6%%3D!5E7!5B1!5BB!5E5!
588!5AB%%26a_y6%%3D1%%26a_o6%%3D0%%26a_v6%%3D!5E5!587!5BA!5E7!5A7!59F
\n",
plow, phigh, slow, shigh);
strcat(buf, tmp);
memset(tmp, 0, sizeof(tmp));
sprintf(tmp, "firefox \"%s\"\n", buf);
return system(tmp);
}
/*************源代码rent.c分界符结束***********************/
编译此程序然后运行,运行方法如下:
如果要找由个人发布的上海市徐家汇区港汇广场附件的出租房,价格在1000-2000元,房子面积在40-60平米,可以这样运行:
./a.out 上海 徐家汇 港汇广场 1000 2000 40 60
同理,应该对其它城市也管用。
以前因为网页上价格和面积是固定的几个选项,没法自定义,所以我写了这个小程序来自己输入价格和面积。现在的网页上好象可以随意填写了,估计用不着了。

JackyZhou

unread,
Oct 14, 2009, 4:22:03 AM10/14/09
to China Linux Fans
一个使用dup2重定向的例子:
/*************源代码dup2.c分界符开始***********************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
int fd; /*file descriptor to the file we will redirect ls's
output */

if ((fd = open("dirlist.txt", O_RDWR | O_CREAT, 00777)) == -1) { /
*open the file */
perror("open");
return 1;
}

dup2(fd, STDOUT_FILENO); /*copy the file descriptor fd into
standard output */
close(fd); /* close the file descriptor as we don't need it
more */

/*execl ls */
execl("/bin/ls", "ls", (char *) 0);

return 0;
}
/*************源代码dup2.c分界符结束***********************/

本来执行一个命令ls后输出会到stdout上的,现在改输出到文件里去了。可以用来捕捉一个程序的屏幕输出。

Microtiger

unread,
Oct 14, 2009, 4:25:12 AM10/14/09
to china-li...@googlegroups.com
good,有好的代码共享啊!谢谢
I want to be a complete engineer - technical genius and sensitive humanist all in one!


2009/10/14 JackyZhou <zhou...@gmail.com>

JackyZhou

unread,
Oct 14, 2009, 4:34:14 AM10/14/09
to China Linux Fans
一个stat函数的用法例子,获取一个文件或目录的属性:
/*************源代码stat.c分界符开始***********************/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int main(int argc, char **argv)
{
int ret;
struct stat buf;
ret = stat(argv[1], &buf);
printf
("ret:%d\nbuf.st_dev:%d\nbuf.st_ino:%d\nbuf.st_mode:%d\nbuf.st_nlink:
%d\nbuf.st_uid:%d\nbuf.st_gid:%d\nbuf.st_rdev:%d\nbuf.st_size:%d
\nbuf.st_blksize:%d\nbuf.st_blocks:%d\n",
ret, buf.st_dev, buf.st_ino, buf.st_mode, buf.st_nlink,
buf.st_uid, buf.st_gid, buf.st_rdev, buf.st_size, buf.st_blksize,
buf.st_blocks);
return 0;
}
/*************源代码stat.c分界符结束***********************/

运行时加一个参数,即要查看的文件或目录名称

JackyZhou

unread,
Oct 14, 2009, 4:39:21 AM10/14/09
to China Linux Fans
用read和write来进行输入和输出:
/*************源代码read_write.c分界符开始***********************/
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
char buf[4] = "";
read(0, buf, 3); /*用read从键盘输入3个字符*/
//printf("%s\n", buf);
write(1, buf, strlen(buf)); /*将输入字符输出*/
return 0;
}
/*************源代码read_write.c分界符结束***********************/

JackyZhou

unread,
Oct 14, 2009, 9:46:29 AM10/14/09
to China Linux Fans
同时支持IPv4和IPv6连接的服务器代码:
/*************源代码tcp_4and6.c分界符开始***********************/
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <netinet/in.h>
#include <unistd.h>
#include <strings.h>

#define MAXDATASIZE 300

int main(int argc, char **argv) //2001:250:1006:313:213:f6ff:fe6c:8790
{
int IPv4_sockfd, IPv4_temp_fd, IPv4_temp_client;
int IPv6_sockfd, IPv6_temp_fd, IPv6_temp_client;
struct sockaddr_in IPv4_server, IPv4_client;
struct sockaddr_in6 IPv6_server, IPv6_client;
int sin_size, sin6_size;
int num4, num6;
int flag = 1;
char msg4[MAXDATASIZE], msg6[MAXDATASIZE];
fd_set fd;
int max;

if (argc != 5) {
printf
("%s <IPv4 port> <dest IPv4 address> <IPv6 port> <dest IPv6
address> \n",
argv[0]);
exit(0);
}


if ((IPv4_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Creating IPv4 socket failed.\n");
exit(1);
}
if ((IPv6_sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
perror("Creating IPv6 socket failed.\n");
exit(1);
}

sin_size = sizeof(struct sockaddr_in);
sin6_size = sizeof(struct sockaddr_in6);

bzero(&IPv4_server, sizeof(IPv4_server));
IPv4_server.sin_family = AF_INET;
IPv4_server.sin_port = htons(atoi(argv[1]));
IPv4_server.sin_addr.s_addr = htonl(INADDR_ANY); // 0.0.0.0 any
local value address
bzero(&IPv6_server, sizeof(IPv6_server));
IPv6_server.sin6_family = AF_INET6;
IPv6_server.sin6_port = htons(atoi(argv[3]));
IPv6_server.sin6_addr = in6addr_any; // ::0 any local value
address

if (setsockopt
(IPv4_sockfd, SOL_SOCKET, SO_REUSEADDR, &flag,
sizeof(int)) == -1) {
perror("IPv4 setsockopt\n");
exit(1);
}
if (setsockopt
(IPv6_sockfd, SOL_SOCKET, SO_REUSEADDR, &flag,
sizeof(int)) == -1) {
perror("IPv6 setsockopt\n");
exit(1);
}

if (bind(IPv4_sockfd, (struct sockaddr *) &IPv4_server, sin_size)
==
-1) {
perror("IPv4 bind error.\n");
exit(1);
}
if (bind(IPv6_sockfd, (struct sockaddr *) &IPv6_server, sin6_size)
==
-1) {
perror("IPv6 bind error.\n");
exit(1);
}
if (listen(IPv4_sockfd, 5) == -1) {
perror("IPv4 listen error.\n");
exit(1);
}
if (listen(IPv6_sockfd, 5) == -1) {
perror("IPv6 listen error.\n");
exit(1);
}

bzero(&IPv4_client, sin_size);
IPv4_client.sin_family = AF_INET;
IPv4_client.sin_port = htons(atoi(argv[1]));
if (inet_pton(AF_INET, argv[2], &IPv4_client.sin_addr) <= 0) {
printf("Wrong dest IPv4 address!\n");
exit(0);
}
bzero(&IPv6_client, sin6_size);
IPv6_client.sin6_family = AF_INET6;
IPv6_client.sin6_port = htons(atoi(argv[3]));
if (inet_pton(AF_INET6, argv[4], &IPv6_client.sin6_addr) <= 0) {
printf("Wrong dest IPv6 address!\n");
exit(0);
}

max = (IPv4_sockfd > IPv6_sockfd ? IPv4_sockfd : IPv6_sockfd);
while (1) {
FD_ZERO(&fd);
FD_SET(IPv4_sockfd, &fd);
FD_SET(IPv6_sockfd, &fd);
if (select(max + 1, &fd, NULL, NULL, NULL) < 0) {
perror("select error\n");
exit(1);
}

if (FD_ISSET(IPv4_sockfd, &fd)) {
if ((IPv4_temp_fd =
accept(IPv4_sockfd, (struct sockaddr *) (&IPv4_client),
&sin_size)) == -1) {
perror("IPv4 accept error\n");
exit(1);
}
num4 = recv(IPv4_temp_fd, msg4, MAXDATASIZE, 0);
if (num4 < 0) {
perror("IPv4 recv error\n");
exit(1);
} else {
msg4[num4] = '\0';
printf("IPv4 message: %s\n", msg4);
if ((IPv6_temp_client =
socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
perror("Creating IPv6 client socket failed.\n");
exit(1);
}
if (connect
(IPv6_temp_client, (struct sockaddr *) (&IPv6_server),
sizeof(IPv6_server)) == -1) {
perror("IPv6 Client connect error\n");
exit(1);
}
if (send(IPv6_temp_client, msg4, num4, 0) == -1) {
perror("IPv6 Client send error\n");
}
close(IPv6_temp_client);
}
close(IPv4_temp_fd);
}

if (FD_ISSET(IPv6_sockfd, &fd)) {
if ((IPv6_temp_fd =
accept(IPv6_sockfd, (struct sockaddr *) (&IPv6_client),
&sin6_size)) == -1) {
perror("IPv6 accept error\n");
exit(1);
}
num6 = recv(IPv6_temp_fd, msg6, MAXDATASIZE, 0);
if (num6 < 0) {
perror("IPv6 recv error\n");
exit(1);
} else {
msg6[num6] = '\0';
printf("IPv6 message: %s\n", msg6);
if ((IPv4_temp_client =
socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("Creating IPv4 client socket failed.\n");
exit(1);
}
if (connect
(IPv4_temp_client, (struct sockaddr *) (&IPv4_server),
sizeof(IPv4_server)) == -1) {
perror("IPv4 Client connect error\n");
exit(1);
}
if (send(IPv4_temp_client, msg6, num6, 0) == -1) {
perror("IPv4 Client send error\n");
}
close(IPv4_temp_client);
}
close(IPv6_temp_fd);
}
}
}
/*************源代码tcp_4and6.c分界符结束***********************/
Message has been deleted

Jacky

unread,
Oct 15, 2009, 1:19:45 AM10/15/09
to China Linux Fans
文件排序,利用生成临时文件x的方法把文件a排序生成文件b,是用磁盘空间换内存的方法,即本方法占用内存较少:
/*************源代码sort.c分界符开始***********************/
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char **argv)
{
char *linebufa = 0, *linebufb = 0, *linebufb_t = 0;
int cmpret, writtenCounter = 0, wrotea =
0, linelena, linelenb, linelent, ret;
FILE *fda, *fdb, *fdt;
fda = fopen(argv[1], "r");
fdb = fopen(argv[2], "w+");

while (1) {
getline(&linebufa, (size_t *) & linelena, fda);
fseek(fdb, 0L, SEEK_SET);
wrotea = 0;
getline(&linebufb, (size_t *) & linelenb, fdb);
if (strcmp(linebufa, linebufb) > 0) {
while (!feof(fdb)) {
ret = getline(&linebufb_t, (size_t *) & linelent, fdb);
if (ret == -1)
break;
if (strcmp(linebufa, linebufb_t) < 0) {
fdt = fopen("/tmp/x.tmp", "w+");
fputs(linebufb_t, fdt);
writtenCounter -= linelent;
while (1) {
getline(&linebufb_t, (size_t *) & linelent, fdb);
fputs(linebufb_t, fdt);
writtenCounter -= linelent;
}
fclose(fdt);
fseek(fdb, writtenCounter, SEEK_SET);
fputs(linebufa, fdb);
writtenCounter += linelena;
fdt = fopen("/tmp/x.tmp", "w+");
while (1) {
getline(&linebufb_t, (size_t *) & linelent, fdt);
fputs(linebufb_t, fdb);
writtenCounter += linelent;
}
fclose(fdt);
remove("/tmp/x.tmp");
wrotea = 1;
}
}
if (wrotea == 0) {
fseek(fdb, writtenCounter, SEEK_SET);
fputs(linebufa, fdb);
writtenCounter += linelena;
}
} else {
fdt = fopen("/tmp/x.tmp", "w+");
writtenCounter = 0;
while (1) {
getline(&linebufb_t, (size_t *) & linelent, fdb);
fputs(linebufb_t, fdt);
}
fclose(fdt);
fseek(fdb, writtenCounter, SEEK_SET);
fputs(linebufa, fdb);
writtenCounter += linelena;
fdt = fopen("/tmp/x.tmp", "w+");
while (1) {
getline(&linebufb_t, (size_t *) & linelent, fdt);
fputs(linebufb_t, fdb);
writtenCounter += linelent;
}
fclose(fdt);
remove("/tmp/x.tmp");
}
}

fclose(fda);
}
/*************源代码sort.c分界符结束***********************/

Jacky

unread,
Oct 15, 2009, 1:28:28 AM10/15/09
to China Linux Fans
select函数使用方法伪代码示例:
/*************伪代码select.txt分界符开始***********************/
select的作用:检测socket状态变化

int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

fd_set rdfds, wtfds, expfds;
struct timeval tmv;
int nfds, retval;

while(1) {
/*清空fd_set,注意每次循环都要做select之前这些事;*/ FD_ZERO(&rdfds); FD_ZERO(&wtfds);
FD_ZERO(&expfds);
/*把要监测的fd加入fd_set*/ FD_SET(0, &rdfds); FD_SET(clientsocketfd1,
&rdfds); FD_SET(clientsocketfd2, &rdfds);
/*找出fd最大值*/if(clientsocketfd1 > 0) nfds = clientsocketfd1 + 1; if
(clientsocketfd2 > clientsocketfd1) nfds = clientsocketfd2 + 1;
/*设定时间*/ tmv.tv_sec = 1;tmv.tv_usec = 0;

retval = select(nfds, &rdfds, &wtfds, &expfds, &tmv); /*检测在指定时间内是否有fd
状态发生变化*/
if(retval == 0) continue; /*所有的fd状态都无变化*/
else if(retval < 0) exit(errno); /*系统出错*/
else { /*某个或多个fd状态发生变化*/
if(FD_ISSET(0, &rdfds)) {/*有按键*/
/*接收键盘上的数据*/
read(0, buf, count);
}
if(FD_ISSET(clientsocketfd1, &rdfds)) {/*client1发送了数据给你*/
/*接收client1上的数据*/
recv(clientsocketfd1);
}
if(FD_ISSET(clientsocketfd2, &rdfds)) {/*client2发送了数据给你*/
/*接收client2上的数据*/
recv(clientsocketfd2);
}
}
}
/*************伪代码select.txt分界符结束***********************/

Jacky

unread,
Oct 15, 2009, 1:38:02 AM10/15/09
to China Linux Fans
epoll几个函数使用方法的伪代码示例:
/*************伪代码epoll_lt.txt分界符开始***********************/
int kdpfd = epoll_create(1);
struct epoll_event ev, events[5];

maxevents = 0;

socketfd = socket();
listen(socketfd);
setnonblocking(socketfd);

selffd = socket();
connect(selffd);
setnonblocking(selffd);

ev.events = EPOLLIN | EPOLLOUT; /**/
ev.data.fd = selffd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, selffd, &ev);
maxevents++;

ev.events = EPOLLIN;
ev.data.fd = socketfd;
epoll_ctl(kdpfd, EPOLL_CTL_ADD, socketfd, &ev);
maxevents++;

for (;;) {
nfds = epoll_wait(kdpfd, events, maxevents, 5);

for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == socketfd) {
clientfd = accept(socketfd, (struct sockaddr *) &local,
&addrlen);
if (clientfd < 0) {
perror("accept");
continue;
}
setnonblocking(clientfd);
ev.events = EPOLLIN;
ev.data.fd = clientfd;
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, clientfd, &ev) < 0) {
fprintf(stderr, "epoll set insertion error: fd=%d\n",
client);
return -1;
}
maxevents++;
} else if (events[n].data.fd == selffd) {
/*selffd上可读或可写数据 */
} else { /*客户端有发来数据*/
handle_fd(events[n].data.fd);
}
}
}
/*************伪代码epoll_lt.txt分界符结束***********************/

Jacky

unread,
Oct 15, 2009, 1:41:47 AM10/15/09
to China Linux Fans
韩国人写的在frame buffer设备(常指嵌入式设备LCD)上显示bmp图片的源代码
/*************源代码drawbmp.c分界符开始***********************/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> /* for O_RDONLY */
#include <sys/mman.h> /* for mmap */
#include <linux/fb.h> /* for fb_var_screeninfo, FBIOGET_VSCREENINFO
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include "bmp.h"

#define FBDEVFILE "/dev/fb"
#define COLS 640
#define ROWS 480

/* 프로그램을 잘못 실행 시킬때 나오는 프로그램 실행방법 */
void usage()
{
printf("\n=====================================\n");
printf("\nUsage: ./drawbmp xxx.bmp \n");
printf("\n=====================================\n");
}

/* bmp파일에서 그림 정보와 데이터를 뽑아 내는 함수 */
/* 교육의 편의성을 위해 24bit 트루 칼러만에서 사용할 수 있음 */
void read_bmp(char *filename, char **pDib, char **data, int *cols, int
*rows)
{
BITMAPFILEHEADER bmpHeader;
BITMAPINFOHEADER *bmpInfoHeader;
unsigned int size;
unsigned char ID[2];
int nread;
FILE *fp;

fp = fopen(filename,"rb");
if(fp == NULL) {
printf("ERROR\n");
return;
}

ID[0] = fgetc(fp);
ID[1] = fgetc(fp);

/* BMP 마크를 확인 */
if(ID[0] != 'B' && ID[1] != 'M') {
fclose(fp);
return;
}

/* bmp 파일에서 BITMAPFILEHEADER 만큼 읽음 */
nread = fread(&bmpHeader.bfSize,1,sizeof(BITMAPFILEHEADER),fp);
size = bmpHeader.bfSize - sizeof(BITMAPFILEHEADER);

/* 위에서 얻은 size만큰 메모리를 잡고 일어서 pDib에 넣음*/
*pDib = (unsigned char *)malloc(size);
fread(*pDib,1,size,fp);

/* 위에서 읽은 pDib에서 BITMAPINFOHEADER를 추출함 */
bmpInfoHeader = (BITMAPINFOHEADER *)*pDib;

/* 24비트 true 칼라 있때만 사용 할 수 있도록 함 */
if(24 != bmpInfoHeader->biBitCount)
{
printf("It supports only 24bit bmp!\n");
fclose(fp);
return;
}

/* BITMAPINFOHEADER에서 가로와 세로 사이즈을 구함 */
*cols = bmpInfoHeader->biWidth;
*rows = bmpInfoHeader->biHeight;

/* 실제 데이터의 주소를 가져옴 */
*data = (char *)(*pDib + bmpHeader.bfOffBits - sizeof(bmpHeader)-2);
fclose(fp);
}

/* 할당한 메모리 해제 */
void close_bmp(char **pDib)
{
free(*pDib);
}

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

int cols, rows;
char *pData,*data;
char r,g,b;
unsigned short bmpdata1[640*480];
unsigned short pixel;
unsigned short *pfbmap;
struct fb_var_screeninfo fbvar;
int fbfd;
int i,j,k,t;


if(argc != 2){
usage();
return 0;
}

/* 프레임 버퍼를 오픈 함 */
fbfd = open(FBDEVFILE, O_RDWR);

if(fbfd < 0){
perror("fbdev open");
exit(1);
}

/* mmap 함수를 이용하여 flame buffer의 메모리의 가상 주소를 얻었냄 */
pfbmap = (unsigned short *)
mmap(0, COLS*ROWS*2,PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0);

if((unsigned)pfbmap == (unsigned)-1)
{
perror("fbdev mmap");
exit(1);
}

/* bmp파일을 읽어 드림 */
read_bmp(argv[1],&pData,&data, &cols,&rows);

/* 한 픽셀에 3byte인것을 2byte로 바꿈 */
for(j=0;j<rows;j++){
k = j*cols*3;
t = (rows -1 - j)*cols;
for(i=0;i<cols;i++)
{
b = *(data + (k + i*3));
g = *(data + (k + i*3+1));
r = *(data + (k + i*3+2));
pixel = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
bmpdata1[t+i] = pixel;
}
}

/* bmp 파일에서 읽은 data를 프레임 버퍼의 메모리로 카피 함 */
memcpy(pfbmap,bmpdata1, COLS*ROWS*2);

/* 활당 받은 메로리들을 해제한 후 프레임 버퍼룰 close 함 */
munmap(pfbmap,ROWS*COLS*2);
close_bmp(&pData);
close(fbfd);
return 0;
}
/*************源代码drawbmp.c分界符结束***********************/

Jacky

unread,
Oct 15, 2009, 1:55:23 AM10/15/09
to China Linux Fans
通过网络发送结构体的研究代码:
/*************源代码send_struct.c分界符开始***********************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>

struct x {
int id;
char name[16];
char addr[16];
} onep;

int main(void)
{
int x, i, len;
unsigned char ch, *p;
memset(&onep, 0, sizeof(onep));
scanf("%d", &onep.id);
printf("id=%d\n", onep.id);
getchar(); /*注意:如果是使用标准C库的一套输入函数,每次输入(scanf之类的函数)之后有回车字符在buffer里*/
read(0, onep.name, 15);
onep.name[strlen(onep.name) - 1] = 0;
read(0, onep.addr, 15);
onep.addr[strlen(onep.addr) - 1] = 0;
printf("id:%d name:%s(len:%d) addr:%s(len:%d)\n", onep.id,
onep.name,
strlen(onep.name), onep.addr, strlen(onep.addr));
len = sizeof(onep);
onep.id=htonl(noep.id); /*非单个字节的数据在网络上发送前要进行host to network转换*/
p = (char *) &onep;
for (i = 0; i < len; i++) {
printf("%02X ", p[i]);
}
printf("\n");
send(socketfd, (void *) &onep, sizeof(onep), 0); /*如果输入的name和addr字符
个数较少,中间将填0发送*/
return 0;
}
/*************源代码send_struct.c分界符结束***********************/

Jacky

unread,
Oct 15, 2009, 2:00:45 AM10/15/09
to China Linux Fans
函数sscanf用法示例:
/*************源代码sscanf.c分界符开始***********************/
#include <stdio.h>

int main(int argc, char **argv)
{

int bufa = 0;
int bufb = 0;
int bufc = 0;
sscanf(argv[1], "%d %d %d", &bufa, &bufb, &bufc);
printf("argv[1]:%s\n", argv[1]);
printf("bufa:%d\n", bufa);
printf("bufb:%d\n", bufb);
printf("bufc:%d\n", bufc);
return 0;
}
/*************源代码sscanf.c分界符结束***********************/

sscanf属于scanf系列函数,scanf从一个FILE *里接收数据,而sscanf从一个char *接收数据。

Jacky

unread,
Oct 15, 2009, 2:06:48 AM10/15/09
to China Linux Fans
网络字节序和主机字节序转换研究:
/*************源代码htonl_do.c分界符开始***********************/
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>

void Prt(unsigned int *p)
{
unsigned char *m;
m = (unsigned char *) p;
printf("m=%x\n", *m);
m++;
printf("m=%x\n", *m);
m++;
printf("m=%x\n", *m);
m++;
printf("m=%x\n\n", *m);
}

int main(int argc, char **argv)
{

unsigned int x;
unsigned int y;
x = atoi(argv[1]);
y = htonl(x);
printf("本机顺序:\n");
Prt(&x);
printf("网络顺序:\n");
Prt(&y);
return 0;
}
/*************源代码htonl_do.c分界符结束***********************/

编译之后给一个比较大的数作为参数来运行,比如:
./a.out 123456789

Reply all
Reply to author
Forward
0 new messages