2010-08-31 37 views
8
char out_file_name[30]; 


ogSize = strlen(FileName); //i.e. - FileName_anylength.log (always.log) 
ogSize -= strlen(IN_FILE_SUFFIX); //amount of chars before .log 

strncpy(out_file_name, FileName, ogSize); //out_file_name now is FileName_anylength (without the .log) 

Đây có phải là cách tốt nhất để làm điều này không?Có cách nào khác để cắt ngắn chuỗi không?

Ngoài ra, làm cách nào để bảo vệ ogSize đó không xảy ra quá 30 ký tự khi nó đến từ đầu vào của người dùng?

Cảm ơn bạn.

+1

Bạn có nghĩa là thêm vào trước? Hoặc khai thác chuỗi? Cắt ngắn? –

+1

Tôi nghĩ rằng bạn có nghĩa là "cắt ngắn" (bạn muốn loại bỏ các yếu tố từ cuối chuỗi, cắt ngắn nó thành một chiều dài ngắn hơn, phải không?) –

+0

cắt ngắn - đó là một. Cảm ơn. Xin lỗi, tiếng Anh là ngôn ngữ đầu tiên của tôi .... có trước tiên, đó là lý do tại sao nó quá tệ. –

Trả lời

17

Với chuỗi kiểu C, bạn chỉ có thể đặt ký tự bạn muốn cắt bớt thành \0.

Về câu hỏi thứ hai của bạn, về cơ bản bạn kiểm tra. Hoặc bạn phân bổ bộ nhớ nhiều như bạn cần, dựa trên kích thước chuỗi (nhớ bao gồm chỗ cho \0).

+1

+1 Bí quyết tốt.Strlen sẽ dừng trên phiên bản đầu tiên của '\ 0' –

+0

@jkerian: Giải pháp tốt, cảm ơn. –

2

này cung cấp cho một cái nhìn:

char *trunc; 
char *outfile; 

strdup(outfile, FileName); 

if (((trunc = strstr(out_file_name, ".log")) != NULL) 
*trunc = '\0'; 

return (outfile); // assumes returning result from function 
+0

strdup không phải là ANSI C (không có C89, không có C99) – user411313

+0

Nó đủ tiêu chuẩn và được sử dụng một cách an toàn trong hầu hết các môi trường: IEEE 1003.1, 2004, (http://www.opengroup.org/onlinepubs/009695399/functions /strdup.html); SVr4, 4.3BSD, POSIX.1-2001 (http://linux.die.net/man/3/strdup) và Unix 98 (http://www.mkssoftware.com/docs/man3/strdup.3. asp). Ngoài ra, giải pháp của tôi không đưa ra giả định về độ dài của chuỗi nguồn và nó giữ nguyên nó. – BillP3rd

2

Lấy câu hỏi cuối cùng của bạn đầu tiên, đảm bảo kích thước tối đa là khá dễ dàng. Thông thường bạn muốn sử dụng fgets để đọc chuỗi. Điều này cho phép bạn chỉ định độ dài tối đa. Ngoài ra, bạn có thể chỉ định kích thước tối đa theo định dạng quét (ví dụ: "%29s" hoặc "%29[^\n]"). Lưu ý sự khác biệt giữa hai: với fgets bạn chỉ định kích thước bộ đệm, nhưng với scanf bạn chỉ định một kích thước nhỏ hơn kích thước bộ đệm (nghĩa là số ký tự tối đa cần đọc).

Đối với câu hỏi đầu tiên: có, thường có những cách tốt hơn. strncpy là một chức năng lạ, ban đầu được viết cho một mục đích khá cụ thể, và (phải trung thực) có lẽ nên được gỡ bỏ khỏi thư viện chuẩn, bởi vì trong khi nó dường như như nó sẽ hữu ích, nó gần như không bao giờ thực sự là.

Tôi có thể sẽ làm những việc khác một chút. Một khả năng sẽ được sử dụng snprintf, một cái gì đó như:

snprintf(
    out_file_name, 
    sizeof(out_file_name), 
    "%*s", 
    strlen(FileName) - strlen(IN_FILE_SUFFIX), FileName); 
+1

nếu out_file_name không phải là mảng, ví dụ của bạn không hoạt động. snprintf không phải là C89 – user411313

2

fgets sử dụng() để đọc các chuỗi từ người sử dụng, như vậy bạn có thể chỉ định một chiều dài tối đa của chuỗi

char* from = FileName; 
char* to = out_file_name; 
int curLen = 0; 

do 
{ 
    *to++=*from++ 
} 
while(*from && *from!='.' && ++curLen < ogSize); 

*to='\0'; 
+1

hoạt động không nhiều hơn một '.' trong số từ – user411313

1

Bạn có thể chèn một null vào chuỗi để rút ngắn nó. Bên dưới hàm strstr() được sử dụng để tìm địa chỉ của lần xuất hiện đầu tiên của ".log". Sau đó, bạn có thể trừ hai địa chỉ với nhau để tìm hiểu độ dài của tên và vị trí chèn null.

int main() { 
    char suffix[] = ".log"; 
    char filename[] = "FileName_anylength.log"; 
    char* end_address = strstr(filename, suffix); 
    filename[end_address-filename] = 0; 
    printf("%s", filename); 
} 
+1

@ BillP3rd - Apologies Bill, chỉ cần nhận thấy chúng tôi có câu trả lời tương tự. Tôi thích của bạn tốt hơn, không trừ. - chúc mừng :) – skimobear

1
char out_file_name[30]; 
char *suffix=".log"; 
size_t IN_FILE_SUFFIX = strlen(suffix); 

/* also works, if suffix occurs more than 1 time or never ! */ 
if(strstr(out_file_name, suffix)) 
    out_file_name[ strlen(out_file_name) - IN_FILE_SUFFIX ] = 0; 

hoặc

char out_file_name[30]; 
char *suffix=".log"; 
size_t IN_FILE_SUFFIX = strlen(suffix); 

/* also works, if suffix occurs more than 1 time or never ! */ 
if(strstr(out_file_name, suffix)) 
{ 
    char format[20]; 
    sprintf(format, "%%.%ds", strlen(out_file_name) - IN_FILE_SUFFIX); 
    sprintf(out_file_name, format, out_file_name); 
} 
Các vấn đề liên quan