Showing posts with label Programming techniques. Show all posts
Shell - Search và Replace trong file
1. Tìm kiếm file với lệnh find
2. Tìm kiếm và thay thế string trong một file với lệnh sed
3. Tìm kiếm file, search và thay thế nội dung file với sự kết hợp của find và sed
find <search dir> -type <file or dir> -name <pattern file name>
Ex:
find /home/user/Downloads -type f -name "*.rar"
Tìm kiếm tất cả các file nén .rar trong thư mục Downloads
2. Tìm kiếm và thay thế string trong một file với lệnh sed
sed -i "s:<string to search>:<string to replace>:" infile outfile
or
sed -i "s:<string to search>:<string to replace>:" filename
# tim, thay the va save filename
Ex:
sed -i "s:day:night:" testfile.txt
3. Tìm kiếm file, search và thay thế nội dung file với sự kết hợp của find và sed
#!/bin/sh
# Tao listfile.txt luu danh sach tat ca cac file trong thu muc Downloads
#find /home/ninhld/Downloads -type f -name '*' > /home/ninhld/Downloads/listfile.txt
#Duyet qua tat ca cac file trong thu muc Downloads, search va replace tat ca
#cac file ma noi dung co noi dung /home/ninhld/Downloads
FINDPATH="/home/ninhld/Downloads"
FILETYPE="*"
PATTERN="/home/ninhld/Downloads"
REPLACE=""
find $FINDPATH -type f -name "$FILETYPE" -exec sed -i "s:$PATTERN:$REPLACE:" {} +
#for FILE in $(find $FINDPATH -type f)
#do
# #echo $FILE
# sed -i "s:$FINDPATH::" $FILE
#done
C/C++ Giá trị khởi tạo ban đầu của biến
Giá trị khởi tạo ban đầu của biến tưởng chừng đơn giản nhưng nhiều khi để lại hậu quả nghiêm trọng, trong bài viết này đề cập đến một số trường hợp bạn phải khởi tạo giá trị bạn đầu cho biến một cách rõ ràng.
initial_value.c (vd chỉ có tính minh họa)
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main(int argc, char **argv){
int idata; /* default: 0 */
bool bdata; /* default: false */
float *pdata; /* default: NULL */
if(!idata){
/* code here */
printf("goto here 1\n");
}
if(!bdata){
/* code here */
printf("goto here 2\n");
}
if(!pdata){
/* code here */
printf("goto here 3\n");
pdata = (float*)malloc(sizeof(float));
}
*pdata = 10;
free(pdata);
return 1;
}
Theo suy luận thông thường, khi khai báo mà không khởi tạo giá trị mặc định cụ thể cho biến thì chúng vẫn được tự động gắn các giá trị default như trên ví dụ trên, và vì vậy bạn thấy ngay các biểu trức if sẽ trả về kết quả là true.
Tuy nhiên trong thực tế (kinh nghiệm người viết bài này đã từng gặp phải) thì các giá trị thực sự mà các biến trên có được không giống như giá trị default đáng ra chúng phải bằng; có thể là idata != 0, bdata = true và pdata != NULL dẫn đến các logic của chương trình bị sai, hoặc chương trình bị crash (thao tác với con trỏ không hợp lệ).
Vì vậy khi gặp ngữ cảnh kiểu như trong vd trên thì tốt nhất bạn phải khởi tạo giá trị tường minh cho các biến:
int idata = 0;
bool bdata = false;
float *pdata = NULL;
Đặc biệt quan trọng trong lập trình C++, bạn nên khởi tạo giá trị cho tất cả các biến thuộc class trong hàm Constructor, và giải phóng bộ nhớ (nếu là con trỏ) trong hàm Destructor.
Ring buffer
1. Cấu trúc
2. Nguyên lý làm việc
3. Cách sử dụng
A single process/thread to process/thread buffer use case
Multiple processes/thread to process/thread use case
Single process/thread to multiple processes/thread use case
Single process/thread to multiple process/thread use case using a dispatcher and multiple queues
4. Source code sample
ringbufer.h
#ifndef RINGBUFFER_H
#define RINGBUFFER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdbool.h>
/*
* ringbuffer.h - C ring buffer (FIFO) interface.
*/
typedef struct ringbuffer_t
{
void *buffer; // data buffer
void *buffer_end; // end of data buffer
size_t capacity; // maximum number of items in the buffer
size_t count; // number of items in the buffer
size_t sz; // size of each item in the buffer
void *head; // pointer to head
void *tail; // pointer to tail
} ringbuffer_t;
bool ring_init(ringbuffer_t *cb, size_t capacity, size_t sz);
bool ring_free(ringbuffer_t *cb);
bool ring_push_head(ringbuffer_t *cb, const void *item);
bool ring_pop_tail(ringbuffer_t *cb, void *item);
#ifdef __cplusplus
}
#endif
#endif /* RINGBUFFER_H */
ringbuffer.c
#include "ringbuffer.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
bool ring_init(ringbuffer_t *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
if(cb->buffer == NULL){
printf("ring_init FAIL ! \n");
return false;
}
cb->buffer_end = (char *)cb->buffer + capacity * sz;
cb->capacity = capacity;
cb->count = 0;
cb->sz = sz;
cb->head = cb->buffer;
cb->tail = cb->buffer;
return true;
}
bool ring_free(ringbuffer_t *cb)
{
if(cb->buffer){
free(cb->buffer);
cb->buffer = NULL;
}else{
return false;
}
return true;
}
bool ring_push_head(ringbuffer_t *cb, const void *item)
{
if(cb->count == cb->capacity){
printf("Ringbuffer is Full ! \n");
return false;
}
memcpy(cb->head, item, cb->sz);
cb->head = (char*)cb->head + cb->sz;
if(cb->head == cb->buffer_end)
cb->head = cb->buffer;
cb->count++;
return true;
}
bool ring_pop_tail(ringbuffer_t *cb, void *item)
{
if(cb->count == 0){
printf("Ringbuffer is Empty ! \n");
return false;
}
memcpy(item, cb->tail, cb->sz);
cb->tail = (char*)cb->tail + cb->sz;
if(cb->tail == cb->buffer_end)
cb->tail = cb->buffer;
cb->count--;
return true;
}
ringbuffer_test.c
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "ringbuffer.h"
#define CAPACITY 10
typedef struct data_t{
int idata;
float fdata;
}data_t;
ringbuffer_t ringbf;
int main(int argc, char **argv)
{
ring_init(&ringbf, CAPACITY, sizeof(data_t));
int i;
data_t tmpdata;
for(i = 0; i < CAPACITY; i++){
tmpdata.idata = i;
tmpdata.fdata = i+1;
ring_push_head(&ringbf, (void*)&tmpdata);
printf("number of items: %d \n", ringbf.count);
}
for(i = 0; i < CAPACITY; i++){
ring_pop_tail(&ringbf, (void*)&tmpdata);
printf("number of items: %d, idata: %d, fdata: %f \n", ringbf.count, tmpdata.idata, tmpdata.fdata);
}
ring_free(&ringbf);
return 0;
}