2014-06-20 23 views
8

Tôi đang tạo ứng dụng khách/máy chủ và muốn tự động gọi các hàm. tôi có tạo ra các cấu trúc sau:Các phần tử không xác định trong mảng cấu trúc

typedef struct _cmd cmd; 
struct _cmd 
{ 
    const char *name; 
    void (*func)(int s,int ac, char **av); 
}; 

Khi client gửi một lệnh đến máy chủ server sẽ duyệt qua một loạt các lệnh:

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update } 
}; 


cmd *find_cmd(const char *name) { 
    cmd *c; 
    for (c = cmds; c->name; c++) { 
     if (stricmp(name, c->name) == 0) 
      return c; 
    } 
    return NULL; 
}  

Xin lưu ý rằng

stricmp() 

không phải là một lỗi đánh máy, nó là một phiên bản không phân biệt dạng chữ của strcmp.

Tôi hiện là sự cố sau. Khi tôi gọi find_cmd() và vượt qua một commmand không hợp lệ, ứng dụng của tôi bị treo. thông báo gỡ lỗi của tôi cho thấy như sau:

Browsing Command: CREATE 
Browsing Command: EXIT 
Browsing Command: LIST 
Browsing Command: READ 
Browsing Command: DELETE 
Browsing Command: UPDATE 
Browsing Command: �p� 
Browsing Command: �(� 

Sau đó tôi nhận được segfault. Điều này nhìn tôi như thể có một số yếu tố không xác định trong mảng structm nhưng nơi nào họ đến từ đâu? Tôi đang nhìn gì? Cảm ơn trước cho bất kỳ con trỏ.

+1

Bạn cần một [sentinel value] (http://en.wikipedia.org/wiki/Sentinel_value) để chấm dứt lệnh list của bạn. Vì đây là một cấu trúc, lệnh null và con trỏ hàm null sẽ hoạt động. – Joe

+1

Không phải là câu trả lời mà chỉ cần lưu ý. Không sử dụng số nhận dạng bắt đầu bằng '_' vì nó được dành riêng để triển khai. – Jack

+0

Cảm ơn các gợi ý, điều này hoạt động tốt, xem bình luận của tôi dưới đây :) –

Trả lời

11

Bạn cần một yếu tố "null" ở cuối danh sách của bạn để kích hoạt thử nghiệm c->name (!= NULL) trong cho bạn vòng lặp.

Thay đổi

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update } 
}; 

để

cmd cmds[] = { 
     { "CREATE", cmd_create }, 
     { "EXIT" , cmd_exit }, 
     { "LIST", cmd_list }, 
     { "READ", cmd_read }, 
     { "DELETE", cmd_delete }, 
     { "UPDATE", cmd_update }, 
     { NULL, NULL } 
}; 
+0

Cảm ơn bạn đã trả lời nhanh chóng, điều này hoạt động như một say mê. Làm cách nào để tôi cần thêm một phần tử NULL, NULL vào danh sách một cách rõ ràng? Tôi không kiểm tra (c-> name == NULL) nhưng trả về NULL khi không tìm thấy gì? –

+1

Nhưng bạn _are_ thử nghiệm 'c-> name == NULL'. Đó là điều kiện chấm dứt trên vòng lặp 'for' của bạn. Đó là những gì biểu thức trung tâm trên câu lệnh 'for'. – DoxyLover

+1

@ Fish-Ruột, điều kiện kết thúc vòng lặp của bạn là 'c-> name' tức là' c-> name! = NULL'. Bằng cách thêm phần tử 'NULL' của sentinel, nó cho phép vòng lặp' for' thoát ra. – DaV

Các vấn đề liên quan