2012-01-11 72 views
8

Chơi với con trỏ trong C là thú vị (không thực sự).Con trỏ tới mảng chuỗi trong C

Tôi có một vài mảng các chuỗi tôi muốn tuyên bố một cách dễ dàng, tốt nhất là một cái gì đó như:

arrayOfStrings1 = {"word1", "word2", etc. }; 
arrayOfStrings2 = {"anotherword1", "anotherword2", etc. }; 
arrayOfStrings3 = etc. 
etc. 

Something tương tự như một mảng dịch (nhưng không hoàn toàn), vì vậy tôi muốn để có thể trao đổi giữa chúng trong thời gian chạy. Cho rằng tôi muốn có một con trỏ pointerToArrayOfStrings mà tôi có thể trao đổi như:

pointerToArrayOfStrings = arrayOfStrings1; 
doStuff(); 
pointerToArrayOfStrings = arrayOfStrings2; 
doSomeOtherStuff(); 

Trong sự hiểu biết ngây thơ của tôi về mảng các chuỗi và con trỏ vào đó, đây là những gì tôi đã cố gắng:

// Danish transforms 
const unsigned char* da_DK[] = {"b","bb","c","c","cc","d","dd","e","f","ff","g","gg","h","hh","j","j","jj","k","k","kk","l","l","l","l","ll","m","mm","n","n","nn","p","pp","r","r","r","rr","s","s","s","ss","t","t","tt","v","v","vv","æ"}; 

// British english transforms 
const unsigned char* en_GB[] = {"a","a","a","a","a","a","a","a","a","a","a","a","a","age","ai","aj","ay","b","cial","cian","cian","dj","dsj","ea","ee","ege","ei","ei","eigh","eigh","f","f","f","g","g","gs","i","i","i","j","j","k","ks","kw","l","m","n","n","o","r","s","s","sd","sdr","sion","sion","sj","sj","tial","tion","tion","tj","u","u","u","u","w","ye","ye","z"}; 

    // More languages.... 

const unsigned char** laguageStrings; 

// Assign language 
if (streq(language, "da-DK")){ 
    laguageStrings= da_DK; 
} 
else if (streq(language, "en-GB")){ 
    laguageStrings= en_GB; 
} 
else 
     return 0; 
} 

Ngôn ngữ là một char * có chứa ngôn ngữ "en-GB", "da-DK", v.v. streq() chỉ là một nhà ủ (hơi nhanh hơn strcmp()) chức năng so sánh chuỗi.

Câu chuyện dài ngắn, tùy thuộc vào trình biên dịch phương pháp này có thể hoạt động, báo cáo cảnh báo trình biên dịch hoặc biên dịch, nhưng cho kết quả không mong muốn.

Cách chính xác để giải quyết vấn đề này là gì?

+0

Sự cố là gì? –

+2

Bạn nên kết thúc mảng chuỗi của bạn với một con trỏ NULL để bạn có thể duyệt chúng một cách hợp lý: 'const char * strs [] = {" aa "," bb ", NULL};' –

+0

Tùy thuộc vào trình biên dịch nó không hoạt động.Trình biên dịch GNU GNU thích nó và hoạt động, XCODE không và tạo ra một số lỗi lạ. – Woodgnome

Trả lời

19

Có hai cách làm việc với mảng ký tự (chuỗi) trong C. Chúng như sau:

char a[ROW][COL]; 
char *b[ROW]; 

Hình ảnh đại diện có sẵn dưới dạng nhận xét nội dòng trong mã.

Dựa vào cách bạn muốn để đại diện cho mảng ký tự (chuỗi), bạn có thể xác định con trỏ đến đó như sau

char (*ptr1)[COL] = a; 
    char **ptr2 = b; 

Họ là loại cơ bản khác nhau (trong một cách tinh tế) và như vậy các con trỏ tới chúng cũng hơi khác một chút.

Ví dụ sau minh họa các cách làm việc khác nhau với các chuỗi trong C và tôi hy vọng nó sẽ giúp bạn hiểu rõ hơn về mảng ký tự (chuỗi) trong C.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define ROW 5 
#define COL 10 

int main(void) 
{ 
    int i, j; 
    char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"}; 
    char *b[ROW]; 

    /* 

    a[][] 

     0 1 2 3 4 5 6  7 8 9 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 1 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 2 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 3 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 4 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 
    | s | t | r | i | n | g | 5 | '\0' | | | 
    +---+---+---+---+---+---+---+------+---+---+ 

    */ 

    /* Now, lets work on b */  
    for (i=0 ; i<5; i++) { 
     if ((b[i] = malloc(sizeof(char) * COL)) == NULL) { 
      printf("unable to allocate memory \n"); 
      return -1; 
     } 
    } 

    strcpy(b[0], "string1"); 
    strcpy(b[1], "string2"); 
    strcpy(b[2], "string3"); 
    strcpy(b[3], "string4"); 
    strcpy(b[4], "string5"); 

    /* 

     b[]    0 1 2 3 4 5 6 7  8 9 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 1 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 2 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 3 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 4 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 
    |  --|------->| s | t | r | i | n | g | 5 | '\0' | | | 
    +--------+  +---+---+---+---+---+---+---+------+---+---+ 

    */ 

    char (*ptr1)[COL] = a; 
    printf("Contents of first array \n"); 
    for (i=0; i<ROW; i++) 
     printf("%s \n", *ptr1++); 


    char **ptr2 = b; 
    printf("Contents of second array \n"); 
    for (i=0; i<ROW; i++) 
     printf("%s \n", ptr2[i]); 

    /* b should be free'd */ 
    for (i=0 ; i<5; i++) 
     free(b[i]); 

    return 0; 
} 
+0

Vì vậy, nếu tôi muốn xác định mảng của tôi của chuỗi như là một 'char * [COLS]' Tôi buộc phải 'malloc()' và sau đó 'strcpy()'? Không có cách nào tôi có thể khởi tạo nó với một danh sách chuỗi như '{" string1 "," string2 ", ...}'? – Woodgnome

+0

Xin lỗi, đó là nghĩa vụ phải là 'char * [ROWS]' – Woodgnome

+2

@Woodgnome Có, bạn không thể gán một chuỗi cho 'char []' hoặc 'char *' như cách bạn chỉ định giá trị nguyên cho biến số nguyên. Đối với chuỗi, bạn cần sử dụng các hàm thư viện chuỗi như 'strcpy()' –

1

Cách nào chính xác để giải quyết vấn đề này?

Vâng, cách chính xác sẽ là sử dụng thư viện được thiết kế đặc biệt để xử lý các giao diện đa ngôn ngữ - ví dụ: gettext.

Một cách khác, mặc dù patchier, sẽ được sử dụng một hash table (còn được gọi là "từ điển" hay "bản đồ băm" hoặc "bản đồ kết hợp" trong các ngôn ngữ khác/công nghệ): Looking for a good hash table implementation in C

Đó là lẽ không phải là câu trả lời bạn đang tìm kiếm, nhưng bạn đã đặt câu hỏi sai cho vấn đề đúng.

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