Khi sử dụng các chuỗi null-terminated (mặc định trong C), bạn có thể thực sự tạo ra một chuỗi con của một chuỗi khác bằng cách thay đổi con trỏ ký tự bắt đầu, nhưng bạn không thể làm cho chuỗi con mới có một null-terminator khác.
Tùy chọn là sử dụng thư viện chuỗi Pascal. Các chuỗi Pascal có độ dài tiền tố thay vì các chuỗi C được kết thúc bằng null, có nghĩa là các chuỗi Pascal có thể chia sẻ nội dung của bộ đệm chuỗi lớn hơn và tạo chuỗi con là giá rẻ (O(1)
-eap). Một chuỗi Pascal trông như thế này:
struct PString {
size_t length;
char* start;
}
PString substring(const PString* source, size_t offset, size_t length) {
// Using C99 Designated Initializer syntax:
return PString { .length = length, .start = source.start + offset };
}
Nhược điểm là hầu hết các thư viện và nền tảng thư viện C sử dụng null-terminated strings và trừ khi Pascal-string của bạn kết thúc bằng một ký tự null bạn sẽ cần phải sao chép các chuỗi con vào bộ đệm mới (trong thời gian O(n)
).
Tất nhiên, nếu bạn đang cảm thấy nguy hiểm (và sử dụng bộ đệm nhân vật có thể thay đổi) sau đó bạn có thể hack nó để tạm thời chèn một null-terminator, như vậy:
struct CStr {
char* start;
char* end;
char temp;
}
CStr getCStr(PString* source) {
char* terminator = (source.start + source.length);
char previous = *terminator;
*terminator = '\0';
return CStr { .start = source.start, .end = terminator, .temp = previous };
}
void undoGetCStr(CStr cstr) {
*cstr.end = cstr.temp;
}
Được sử dụng như sau:
PString somePascalString = doSomethingWithPascalStrings();
CStr temp = getCStr(somePascalString);
printf("My Pascal string: %s", temp.start); // using a function that expects a C-string
undoGetCStr(temp);
... sau đó cho bạn hiệu suất O(1)
PString-to-CString, miễn là bạn không quan tâm đến tính an toàn của luồng.
Ngoài câu trả lời tốt này là một thực tế là bạn cũng có thể sao chép chất nền từ chuỗi gốc ngược lại bằng cách sử dụng vòng lặp for. –
'memmove', không giống như' memcpy', sẽ cho phép nguồn và đích trùng lặp. Bạn không cần phải phát minh lại nó với một vòng lặp rõ ràng. –