到底 if 之後要不要接 else 呢?
問題總是沒有永遠對的答案
if statement 後面可以沒有 else statement
但有 else statement 總是不會出錯
有多少的bugs, 是掛在這種邏輯問題上面
大部分的人會先注意如何 function work
等到 function work 之後, 也接近準備 release 階段
很容易沒有考慮到 exception 的發生
這對應到 code 的本身
也就是
只注意到 if 成立之後, 而忽略 if 失敗的另一面
為了避免遇到這樣的問題
最好是根據code的大小來安排code配置
比如先寫比較短的程式碼 再寫比較長的程式碼
if (1) {
/* short successful statement */
} else {
/*
...
long failure statement
...
*/
}
or on the contrary,
if (!0) {
/* short failure statement */
} else {
/*
...
long successful statement
...
*/
}
Showing posts with label example. Show all posts
Showing posts with label example. Show all posts
Monday, August 06, 2007
Tuesday, June 05, 2007
Message Queue example
The time to use Message Queue I know is internal logging, and that's the way it used.
msgq_rcv <- MSG Queue <- msgq_snd
sample code below,
msgq.h
msgq_rcv.c
msgq_snd.c
msgq_rcv <- MSG Queue <- msgq_snd
sample code below,
msgq.h
#ifndef _MSGQ_H_
#define _MSGQ_H_
#define MSGQ_PATH "/tmp"
#define MSGQ_ID 111
#define MSG_LEN 128
typedef struct {
long mtype; // MUST
time_t time;
char msg[MSG_LEN+1];
} msgq_t ;
#endif /* _MSGQ_H_ */
msgq_rcv.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>
#include "msgq.h"
int main(int argc, char *argv[])
{
key_t key;
int msgqid;
msgq_t msg;
if ( (key=ftok(MSGQ_PATH, MSGQ_ID)) == -1) {
perror("ftok");
return -1;
}
if ( (msgqid = msgget(key, 0666|IPC_CREAT)) == -1) {
perror("msgget");
return -1;
}
while (1) {
if (-1==msgrcv(msgqid, &msg, sizeof(msg), 0, 0)) {
perror("msgrcv");
return -1;
}
printf("%s->%s\n", ctime(&msg.time), msg.msg);
}
return 0;
}
msgq_snd.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>
#include <string.h>
#include "msgq.h"
int main(int argc, char *argv[])
{
key_t key;
int msgqid;
msgq_t msg;
if ( (key=ftok(MSGQ_PATH, MSGQ_ID)) == -1) {
perror("ftok");
return -1;
}
if ( (msgqid = msgget(key, 0666|IPC_CREAT)) == -1) {
perror("msgget");
return -1;
}
while (1) {
memset(&msg, 0x00, sizeof(msg));
msg.mtype = 1; // MUST
fgets(msg.msg, sizeof(msg.msg)-1, stdin);
time(&(msg.time));
if (-1==msgsnd(msgqid, (msgq_t*)&msg, sizeof(msg), 0)) {
perror("msgsnd");
return -1;
}
}
}
read/write the binary content to file
An example shown here to present
1) how to write the binary content to a file
2) and then read the content from it
Some steps
1) Prepare chunks of memory
Usually the content will be records of memory of any structure type, in case it can be restored back with the structure in step4.
2) Output to a file
Open a file first by open()/fopen(), and then write the records to the file by write()/fwrite(). Of course, all the content can be written once or one by one, it depends on your design decision. Remember to close the file at last.
3) Input the file
We want to read the binary content. First we should open the file and read the content by read()/fread(). How many size we need? Actually, we would not have no idea the real amount of record, but we know the basic element should be the original structure type. so we can use the structure as the element size and then get the chunks of the same size one by one. Finally and without any exception, when we can get nothing, we have gotten all the records without any damage.
4) Recognize the content
The way to recognize the binary content is usually to cast the binary record to be of the original structure type.
Pitfall here,
Usually, we can get the exact all the records without any damage. But exceptions always happen around, so we should have some preventions in hand. The common exception here is the damaged data, so how to make sure the data integrity is the major task. A way to keep data integrity is append the checksum to the real data. so before storing the data, we calculating the checksum and append the result to the data, and after we read the content, we calculate the checksum and compare with the old one. If they match, the data isn't damaged. If not, trouble happened.
Another issue concerned here is the structure layout. Usually, the structure size will always be the multiples of 4, which is defined by the WORD size of the processor. If the actual size is not the multiples of 4, the compiler will expand it to be the multiples by stuffing the hole up. So make sure the structure as compact as possible.
Issue of binary data exchange between different byte order systems is also the problem. It should be the responsibility of the application of upper layer to make sure the portability.
Usually, hexdump is alwasy useful to dump the binary content out.
1) how to write the binary content to a file
2) and then read the content from it
Some steps
1) Prepare chunks of memory
Usually the content will be records of memory of any structure type, in case it can be restored back with the structure in step4.
2) Output to a file
Open a file first by open()/fopen(), and then write the records to the file by write()/fwrite(). Of course, all the content can be written once or one by one, it depends on your design decision. Remember to close the file at last.
3) Input the file
We want to read the binary content. First we should open the file and read the content by read()/fread(). How many size we need? Actually, we would not have no idea the real amount of record, but we know the basic element should be the original structure type. so we can use the structure as the element size and then get the chunks of the same size one by one. Finally and without any exception, when we can get nothing, we have gotten all the records without any damage.
4) Recognize the content
The way to recognize the binary content is usually to cast the binary record to be of the original structure type.
Pitfall here,
Usually, we can get the exact all the records without any damage. But exceptions always happen around, so we should have some preventions in hand. The common exception here is the damaged data, so how to make sure the data integrity is the major task. A way to keep data integrity is append the checksum to the real data. so before storing the data, we calculating the checksum and append the result to the data, and after we read the content, we calculate the checksum and compare with the old one. If they match, the data isn't damaged. If not, trouble happened.
Another issue concerned here is the structure layout. Usually, the structure size will always be the multiples of 4, which is defined by the WORD size of the processor. If the actual size is not the multiples of 4, the compiler will expand it to be the multiples by stuffing the hole up. So make sure the structure as compact as possible.
Issue of binary data exchange between different byte order systems is also the problem. It should be the responsibility of the application of upper layer to make sure the portability.
#include <stdio.h>
#include <time.h>
#include <string.h>
#define USER_LEN 10
#define PASS_LEN 10
#define TOTAL_ACCOUNTS 10
typedef struct {
time_t create_time;
char user[USER_LEN+1];
char pass[PASS_LEN+1];
char reserved[2];
} account_t ;
int main(int argc, char *argv[])
{
int i=0;
FILE *fd;
account_t acc[TOTAL_ACCOUNTS];
// writer
memset(acc, 0x00, sizeof(acc[0])*TOTAL_ACCOUNTS);
for (i=0; i< TOTAL_ACCOUNTS; ++i) {
snprintf(acc[i].user, sizeof(acc[0].user)-1, "user%d", i);
snprintf(acc[i].pass, sizeof(acc[0].pass)-1, "pass%d", i);
time(&acc[i].create_time);
}
fd = fopen("accounts.bin", "wb");
fwrite(acc, sizeof(acc[0]), TOTAL_ACCOUNTS, fd);
fclose(fd);
// reader
memset(acc, 0x00, sizeof(acc[0])*TOTAL_ACCOUNTS);
fd = fopen("accounts.bin", "rb");
for (i=0; !feof(fd) ; ++i) {
fread(&acc[i], sizeof(acc[0]), 1, fd);
if ( feof(fd) ) // A pitfall here
break;
printf("%d,%s/%s/%s\n", i, acc[i].user, acc[i].pass
, ctime(&acc[i].create_time) );
}
fclose(fd);
return 0;
}
Usually, hexdump is alwasy useful to dump the binary content out.
Subscribe to:
Posts (Atom)