2016-12-24 10 views
5

Tôi cần nhận chuỗi động nhưng khi cần nhiều hơn một chuỗi, tôi cần sử dụng các hàm. Cho đến nay tôi đã viết này (tôi đặt // **** ở nơi tôi nghĩ rằng có thể là sai)Lấy chuỗi có hàm C

char* getstring(char *str); 

int main() { 

    char *str; 
    strcpy(str,getstring(str));//***** 
    printf("\nString: %s", str); 
    return 0; 
} 

char* getstring(char str[]){//***** 
    //this part is copy paste from my teacher lol 
    char c; 
    int i = 0, j = 1; 
    str = (char*) malloc (sizeof(char)); 
    printf("Input String:\n "); 
    while (c != '\n') {//as long as c is not "enter" copy to str 
     c = getc(stdin); 
     str = (char*)realloc(str, j * sizeof(char)); 
     str[i] = c; 
     i++; 
     j++; 
    } 
    str[i] = '\0';//null at the end 
    printf("\nString: %s", str); 
    return str;//****** 
} 

printf trong hàm đang làm việc nhưng không trở lại trong main chức năng. Tôi đã thử trả lại void, loại bỏ *s hoặc thêm, thực hiện str2 khác và truy cập vào strcpy ở đó hoặc không sử dụng strcpy. Không có gì có vẻ hiệu quả. Tôi có bỏ lỡ điều gì đó không? Hoặc có thể điều này là không thể ở tất cả // Cảm ơn bạn rất nhiều cho câu trả lời của bạn

+0

Chúng tôi phải đấu tranh trong năm 1 ở đây. Những thứ dễ dàng trong C là không bao giờ dễ dàng cho hơn 5% số người. –

+6

yêu cầu giáo viên của bạn ngừng truyền malloc – coderredoc

+0

@coderredoc Đúc là tùy chọn? Tôi sẽ tự kỷ luật, nếu không có gì khác. –

Trả lời

3

Lấy phần chuỗi có thể được lấy từ answer này. Chỉ đặt \n làm đầu vào cho chức năng getline.

char * p = getline('\n'); 

Ba điều: - không đúc malloc, kiểm tra xem malloc/realloc là thành công và sizeof không phải là một hàm.

+0

' sizeof' có thể không phải là một hàm nhưng không tuân theo cú pháp của hàm! Giống như C# typeof() từ khóa builtin –

+1

@PaulStelian .: yep – coderredoc

3

Sự cố không phải với chức năng bạn đang sử dụng, nhưng với cách bạn thử sao chép kết quả của nó vào một con trỏ chưa được khởi tạo.

Tin tốt là bạn không cần phải sao chép - chức năng của bạn đã phân bổ một chuỗi trong bộ nhớ động, vì vậy bạn có thể sao chép các con trỏ trực tiếp:

char *str = getstring(str); 

này cần khắc phục vụ tai nạn. Một vài điểm cần xem xét để thực hiện chức năng của bạn tốt hơn:

  • main nhu cầu để free(str) khi nó được thực hiện để tránh bộ nhớ bị rò rỉ
  • cửa hàng realloc kết quả trong một con trỏ tạm thời, và làm một tấm séc NULL để xử lý ra tình huống notice-bộ nhớ đúng
1

Hãy đơn giản hóa mã một chút:

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

char* getstring() 
{ 
    char c = 0; 
    int i = 0, j = 2; 
    char *str = NULL; 

    if ((str = (char*) malloc(sizeof(char))) == NULL) 
     return NULL; 

    printf("Input String: "); 
    while (c = getc(stdin)) { 
     if (c == '\n') break; 

     str = (char*) realloc(str, j * sizeof(char)); 
     str[i++] = c; 
     j++; 
    } 
    str[i] = '\0'; 
    printf("getstring() String: %s\n", str); 
    return str; 
} 

int main() 
{ 
    char *str = getstring(); 
    printf("main() String: %s\n", str); 
    free(str); 
    return 0; 
} 

Sau đó thực hiện:

$ make teststring && ./teststring 
cc  teststring.c -o teststring 
Input String: asdfasfasdf 
getstring() String: asdfasfasdf 
main() String: asdfasfasdf 
+1

Vui lòng giải thích mã của bạn. Tôi đang downvoting. – Sibidharan

+1

Bạn dường như không đưa ra những nhận xét trước đó về 'j'. –

+2

... và 'while (c! = '\ N')' là hành vi không xác định lần đầu tiên - uninitialised. –

3

Có hai điều để lấy đi từ bài học như nó đứng bây giờ:

(1) Bạn nên có một cách để trở về tham chiếu đến chuỗi mới, hoặc như là một đối số được truyền bằng tham chiếu đến hàm OR như một giá trị trả về; bạn không nên triển khai cả hai.

(2) Bởi vì chương trình con mà giáo viên đã cấp cho bạn cấp phát bộ nhớ trên heap, nó sẽ có sẵn cho bất kỳ phần nào của chương trình của bạn và bạn không phải tự mình cấp phát bộ nhớ. Bạn nên nghiên cứu sự khác biệt giữa bộ nhớ heap, bộ nhớ toàn cầu và bộ nhớ tự động (stack) để bạn hiểu sự khác biệt giữa chúng và biết cách làm việc với từng loại.

(3) Vì bộ nhớ đã được cấp phát trên heap nên không cần sao chép chuỗi.

Với những sự kiện, mã của bạn có thể được đơn giản hóa để giống như sau:

int main() { 

    char *str = getstring(); 
    printf("\nString: %s", str); 
    return 0; 
} 

char* getstring(){ 
    .... etc 

Trong tương lai, bạn muốn suy nghĩ về cách bạn de-phân bổ bộ nhớ trong chương trình của bạn. Ví dụ, trong đoạn mã này chuỗi không bao giờ được phân bổ. Đó là một thói quen tốt để suy nghĩ về chiến lược của bạn cho de-phân bổ bất kỳ bộ nhớ mà bạn phân bổ.

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