Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 13 kết quả

Đề tài: Vấn đề về dùng con trỏ khi xử lý chuỗi.

  1. #1
    Ngày gia nhập
    10 2007
    Bài viết
    24

    Mặc định Vấn đề về dùng con trỏ khi xử lý chuỗi.

    Yêu cầu là tôi muốn làm một cái hàm nối chuỗi s2 vào chuỗi s1.Nhưng mà mới tập làm wen với con trỏ thôi nên chưa biết bị sự cố jì...Mong các anh em giải thích dùm làm sao mà đoạn code bị lỗi vậy.cám ơn nhiều!

    --Mong các bạn có thể code cho tôi một Chương trình demo về sử dụng con trỏ để xử lý chuỗi nhé...Nếu ko tiện thì cho một cái link cũng đc...Nhưng phải bằng con trỏ nha...Cámơn++

    C++ Code:
    1. #include <iostream.h>
    2. #include <string.h>
    3. char *noichuoi(char *s1, char *s2)
    4. {
    5.     int len1 = strlen(s1);
    6.     int len2 = strlen(s2);
    7.     char *s2Ptr = s2;
    8.     char *result;
    9.     result = s1;
    10.     for(;*s2Ptr!='\0';++s2Ptr)
    11.     {
    12.         result[len1++] = *s2Ptr;
    13.     }
    14.     result[len1+len2] = '\0';
    15.     return(result);
    16. }
    17.  
    18. int main()
    19. {
    20.     char *src="congdong";
    21.     char *dest="cviet";
    22.     char *result;
    23.     result = noichuoi(src,dest);
    24.     cout <<result<<endl;
    25.     return(0);
    26. }
    Đã được chỉnh sửa lần cuối bởi khoadangnguyen : 31-03-2008 lúc 10:13 AM.

  2. #2
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Tình hình là : result là local, khi hàm kết thúc nó chẳng có trả về gì cả. Với lại result cũng chẳng có gì để trả về, nó chỉ là 1 con trỏ trỏ tới chuỗi, không hề có chuỗi nào mới được sinh ra. Lỗi thì nhiều lắm T_T. Dùng new char[], trả về 1 con trỏ static thì ok. nhớ là phải delete[] cho nó luôn, thử lại đi tui sẽ giúp.

  3. #3
    Ngày gia nhập
    10 2007
    Bài viết
    24

    - Uh nhưng tui chỉ hiểu new char[] là cấp phát động một chuỗi thôi.Còn lại mù tịt chẳng hiểu gì cả...Bạn có thể cho thử một ví dụ xem sao.Tôi sẽ nghiên cứu và hỏi sau.

    =>Một chuơng trình demo về xử lý chuỗi sử dụng con trỏ...hay cái link nào cũng đc...

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Example :
    C++ Code:
    1. #include <iostream>
    2. using std::size_t;
    3.  
    4. inline unsigned length_of(const char* s){
    5.   int count = 0;
    6.   for(;*s != '\0'; ++s)
    7.     ++count;
    8.   return count;
    9. }
    10.  
    11. char* append_string(char* s1,char* s2){
    12.   size_t str_size = length_of(s1) + length_of(s2);
    13.   char* new_string = new char[str_size + 1];
    14.  
    15.   char* p = new_string;
    16.   for(;*s1 != '\0' ;++s1)
    17.     *p++ = *s1;
    18.   for(;*s2 != '\0' ;++s2)
    19.     *p++ = *s2;
    20.  
    21.   *p = '\0';
    22.   return new_string;
    23. }
    24.  
    25. int main(){
    26.   char* s1 = "abc";
    27.   char* s2 = "def";
    28.  
    29.   char* result = append_string(s1, s2);
    30.   std::cout << result;
    31.  
    32.   delete[] result;
    33. }

  5. #5
    Ngày gia nhập
    10 2007
    Bài viết
    24

    - bạn nhiệt tình wá! cám ơn nhiều lắm!Tui sẽ research và nếu thắc mắc thì mong bạn giúp đỡ

  6. #6
    Ngày gia nhập
    10 2007
    Bài viết
    24

    Mặc định Vấn đề về dùng con trỏ khi xử lý chuỗi.

    - Cho hỏi cái này nhé...bạn bảo là khai báo static nhưng trong đoạn code của bạn tui thấy static chỗ nào đâu?Khai báo static là để dữ liệu ko bị mất đi khi ra khỏi hàm đúng hok?

    C++ Code:
    1. char* append_string(char* s1,char* s2){
    2.   size_t str_size = length_of(s1) + length_of(s2);
    3.   char* new_string = new char[str_size + 1];
    4.  
    5.   char* p = new_string;
    6.   for(;*s1 != '\0' ;++s1)
    7.     *p++ = *s1;
    8.   for(;*s2 != '\0' ;++s2)
    9.     *p++ = *s2;
    10.  
    11.   *p = '\0';
    12.   return new_string;
    13. }

    Trong đoạn code trên thì p trỏ vào new_string. Vậy tại sao khi hàm trả về ko return(p) mà return(new_string) mới được?...Khi mình dùng con trỏ char new_string xin cấp phát tại sao ko sử dụng luôn nó trong hai vòng lặp luôn mà phải dùng biến trỏ p làm jì nhỉ?Cám ơn nhiều

    C++ Code:
    1. for(;*s1 != '\0' ;++s1)
    2.     *new_string++ = *s1;
    3.   for(;*s2 != '\0' ;++s2)
    4.     *new_string++ = *s2;

  7. #7
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Ý tui là có 2 cách, 1 là dùng khai báo 1 mãng static ví dụ :
    C++ Code:
    1. static new_string[MAX_SIZE];
    2. char* p = new_string;
    Dùng cái này thì không dùng kiểu run-time được vì size của nó là fixed rùi. Dùng cấp phát động vẫn hay hơn. Nếu muốn thì tui cho ví dụ với kiểu static.
    Trong đoạn code trên thì p trỏ vào new_string. Vậy tại sao khi hàm trả về ko return(p) mà return(new_string) mới được?...Khi mình dùng con trỏ char new_string xin cấp phát tại sao ko sử dụng luôn nó trong hai vòng lặp luôn mà phải dùng biến trỏ p làm jì nhỉ?Cám ơn nhiều
    Con trỏ p để thao tác trên vùng nhớ cấp phát cho new_string, cho nên không thể trả về *p được. Và không thể dùng thằng new_string++ được vì bản chất nó là con trỏ const char*, nó sẽ luôn trỏ vào phần tử đầu của vùng nhớ cấp phát trên heap, nếu cậu move nó ++ tức là khi đó giả sử nó đang giữ 1 vùng nhớ 5 phần tử char 1 byte.
    [a][b][c][d][e]
    Nó đang trỏ vào [a] nếu cậu ++ nó sẽ hiểu không phải qua [b] mà move sang vùng nhớ khác, kế bên thằng [e] ( bộ nhớ máy tính tổ chức là 1 hàng ), vì nó là con trỏ dạng mãng chứ không phải đơn thuần là con trỏ thường, nó là const char*. Cậu truy xuất đến 1 phần tử khác được nhưng cậu không thể nói nó trỏ sang 1 thằng khác. Compiler nó không cho cậu generate kiểu đó vì vậy cậu bắt buộc phải dùng 1 con trỏ phụ để thao tác trên nó.
    C++ Code:
    1. int main(){
    2.   char* s1 = "abc";
    3.   char* s2 = "def";
    4.  
    5.   char* result = append_string(s1, s2);
    6.   std::cout << result << "\n\n";
    7.   char *oss = new char[5];
    8.   for(int x= 0; x < 4; ++x){
    9.     oss[x] = 'a';
    10.   }
    11.   oss[4] = '\0';
    12.   //oss++; comment out to see amazing things.
    13.   std::cout << oss << "\n\n";
    14.   delete[] result;
    15.   delete [] oss;
    16. }
    TUi đã làm y chang 1 ví dụ trên, cậu thử comment out dòng oss++ thì sẽ thấy compiler nó complain cỡ nào liền, cho cậu coi cái g++ của tui nó la làng đây :
    Code:
    *** glibc detected *** ./test: free(): invalid pointer: 0x0804a019 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7ce3d65]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7ce7800]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7eacd81]
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7eacddd]
    ./test(__gxx_personality_v0+0x270)[0x80487f4]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7c90050]
    ./test(__gxx_personality_v0+0x3d)[0x80485c1]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 08:03 702357     /home/chan/Desktop/temp1/test
    08049000-0804a000 rw-p 00000000 08:03 702357     /home/chan/Desktop/temp1/test
    0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
    b7b00000-b7b21000 rw-p b7b00000 00:00 0 
    b7b21000-b7c00000 ---p b7b21000 00:00 0 
    b7c79000-b7c7a000 rw-p b7c79000 00:00 0 
    b7c7a000-b7dbe000 r-xp 00000000 08:03 1518597    /lib/tls/i686/cmov/libc-2.6.1.so
    b7dbe000-b7dbf000 r--p 00143000 08:03 1518597    /lib/tls/i686/cmov/libc-2.6.1.so
    b7dbf000-b7dc1000 rw-p 00144000 08:03 1518597    /lib/tls/i686/cmov/libc-2.6.1.so
    b7dc1000-b7dc4000 rw-p b7dc1000 00:00 0 
    b7dc4000-b7dce000 r-xp 00000000 08:03 1485126    /lib/libgcc_s.so.1
    b7dce000-b7dcf000 rw-p 0000a000 08:03 1485126    /lib/libgcc_s.so.1
    b7dcf000-b7dd0000 rw-p b7dcf000 00:00 0 
    b7dd0000-b7df3000 r-xp 00000000 08:03 1518602    /lib/tls/i686/cmov/libm-2.6.1.so
    b7df3000-b7df5000 rw-p 00023000 08:03 1518602    /lib/tls/i686/cmov/libm-2.6.1.so
    b7df5000-b7edd000 r-xp 00000000 08:03 164252     /usr/lib/libstdc++.so.6.0.9
    b7edd000-b7ee0000 r--p 000e8000 08:03 164252     /usr/lib/libstdc++.so.6.0.9
    b7ee0000-b7ee2000 rw-p 000eb000 08:03 164252     /usr/lib/libstdc++.so.6.0.9
    b7ee2000-b7ee8000 rw-p b7ee2000 00:00 0 
    b7efc000-b7eff000 rw-p b7efc000 00:00 0 
    b7eff000-b7f19000 r-xp 00000000 08:03 1485168    /lib/ld-2.6.1.so
    b7f19000-b7f1b000 rw-p 00019000 08:03 1485168    /lib/ld-2.6.1.so
    bfa89000-bfa9f000 rw-p bfa89000 00:00 0          [stack]
    ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
    Aborted (core dumped)

  8. #8
    Ngày gia nhập
    01 2008
    Bài viết
    240

    Trích dẫn Nguyên bản được gửi bởi rox_rook Xem bài viết
    Tình hình là : result là local, khi hàm kết thúc nó chẳng có trả về gì cả. Với lại result cũng chẳng có gì để trả về, nó chỉ là 1 con trỏ trỏ tới chuỗi, không hề có chuỗi nào mới được sinh ra. Lỗi thì nhiều lắm T_T. Dùng new char[], trả về 1 con trỏ static thì ok. nhớ là phải delete[] cho nó luôn, thử lại đi tui sẽ giúp.
    Nguyên nhân không phải như vậy. Mà do con trỏ result bạn chưa cấp phát bộ nhớ cho nó
    result =(char*)malloc(100*sizeof(char))
    Time

  9. #9
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Nguyên nhân không phải như vậy. Mà do con trỏ result bạn chưa cấp phát bộ nhớ cho nó
    result =(char*)malloc(100*sizeof(char))
    Really ? Don't you know what's different between malloc-free and new-delete ?
    Tình hình là : result là local, khi hàm kết thúc nó chẳng có trả về gì cả. Với lại result cũng chẳng có gì để trả về, nó chỉ là 1 con trỏ trỏ tới chuỗi, không hề có chuỗi nào mới được sinh ra
    Read before say so !!!

  10. #10
    Ngày gia nhập
    10 2007
    Bài viết
    24

    Bởi Rox_Rook
    Nó đang trỏ vào [a] nếu cậu ++ nó sẽ hiểu không phải qua [b] mà move sang vùng nhớ khác, kế bên thằng [e] ( bộ nhớ máy tính tổ chức là 1 hàng ), vì nó là con trỏ dạng mãng chứ không phải đơn thuần là con trỏ thường, nó là const char*. Cậu truy xuất đến 1 phần tử khác được nhưng cậu không thể nói nó trỏ sang 1 thằng khác. Compiler nó không cho cậu generate kiểu đó vì vậy cậu bắt buộc phải dùng 1 con trỏ phụ để thao tác trên nó
    - Tớ có tìm tài liệu về con trỏ hằng xem và đồng ý với những điều cậu đã nói nhưng mà tờ có đưa ra một thắc mắc sau: xem ví dụ:
    C++ Code:
    1. #include <iostream>
    2.  
    3. int main()
    4. {
    5.     int *Ptr;
    6.     Ptr = new int [10];
    7.     for(int i=0;i<10;i++)
    8.     {
    9.         *(Ptr+i) = i; //Vấn đề đang nói chỗ này...
    10.     }
    11.  
    12.     for(int j=0;j<10;j++)
    13.     {
    14.         std::cout<<*(Ptr+j)<<"\n";
    15.     }
    16.     return (0);
    17. }

    - Tại sao *(Ptr+i) là đúng luật và hoàn toàn ko có lỗi.Nhưng *(Ptr++) hay *(Ptr + 1) hay *(Ptr + a) (với a là một số cụ thể)...thì lại bị lỗi nhỉ..Theo chủ quan tớ nghĩ thì khi chạy vòng lặp i thì *(Ptr+i) khác nào so với *(Ptr+số cụ thể) nhỉ?

Các đề tài tương tự

  1. Trích chuỗi con trong một chuỗi bằng cách dùng memcpy bằng cách nào?
    Gửi bởi ducvtcpi trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 2
    Bài viết cuối: 05-04-2013, 03:58 PM
  2. Bài tập C++ Dùng strtok cắt chuỗi và lỗi khi dùng atof() chuyển char sang float
    Gửi bởi salomontong trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 1
    Bài viết cuối: 10-03-2012, 05:18 PM
  3. Con trỏ trên C Ghép chuỗi dùng con trỏ
    Gửi bởi kokichi911 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 5
    Bài viết cuối: 15-11-2011, 12:02 AM
  4. Trả lời: 1
    Bài viết cuối: 29-06-2011, 12:02 AM
  5. Xử lý chuỗi không dùng hàm
    Gửi bởi ceny trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 3
    Bài viết cuối: 07-04-2010, 03:09 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn