01/10/2018, 16:27

Bài tập liên quan tới pointer

mình có một đoạn code như thế này

#include<stdio.h>

char *getFirstPt(char target, char *str[]);

int main(){
  char *str[100];
  char target;
  int d;
  
  scanf("%s
",*str);
  scanf("%c",&target);
  
  printf("%s",*getFirstPt(target,str));
  return 0;
}

char *getFirstPt(char target, char *str[]){
  char p[100];
  int i,j;
  
  *str = &p[0];
  for(i=0; *str[i] != '';i++){
    if(*str == &target){
      return *str;
      break;
    }
  }
}

đoạn code này là nhập một dãy dữ liệu bất kỳ (1) từ bàn phím, sau đó nhập một ký tự bất kỳ(2). đoạn code trên sẽ tìm trong dãy dữ liệu bất kỳ(1) ký tự bất kỳ (2) và in ra màn hình đoạn ký tự (3) tính từ vị trí của ký tự (2) tới hết đoạn dữ liệu (1)
VD:
(1) ancdfljsadlkfjlw
(2) d
(3) dfljsadlkfjlw

cách hoạt động của nó đại khái là như thế nhưng khi mình dịch để chạy thử thì nó xuất hiện lỗi sau

 gcc kadai6.c
kadai6.c: In function ‘main’:
kadai6.c:13:12: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
   printf("%s",*getFirstPt(target,str));
           ~^  ~~~~~~~~~~~~~~~~~~~~~~~
           %d

mình không thể hiểu được vì str mình định dạng nó là char, vậy thì sao nó cứ bắt mình đổi lại là %d ???
dĩ nhiên là mình có thử đổi sang %d và dịch thử thì ngạc nhiên là nó dịch được nhưng khi chạy thử thì sau khi mình nhập hai giá trị “str” và “target” thì nó báo " core dumped"

 ./a.out
alsdkjflsdjlf
d
Segmentation fault (core dumped)

ai đó có thể giải thích cho mình với được không???

Pham Van Hai viết 18:43 ngày 01/10/2018

printf("%s",*getFirstPt(target,str));

Bạn sửa lại cách gọi hàm printf("%s", getFirstPt(target,str));.

rogp10 viết 18:32 ngày 01/10/2018

kadai6.c: In function ‘main’: kadai6.c:13:12: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=] printf("%s",*getFirstPt(target,str));

Bởi vì getFirstPt trả về char*, có * vào là deref, nên mới báo là không khớp nhau. (và sẽ nảy sinh vấn đề khi int được đọc như mem)
Nhưng vấn đề chính ở đây lại là câu char *str[100] !!! Đây mới đúng là đầu mối sự việc.

nya nguyen viết 18:42 ngày 01/10/2018

ôi mình cũng hỏi ông thầy như thế và được giải thích rằng vì "str " đang là “*str” nên “get…” cũng phải cùng là "*get… "
một vài ví dụ của ông ấy vẫn sử dụng như thế và đều chạy bình thường

rogp10 viết 18:28 ngày 01/10/2018
  • Deref một biểu thức thì có gì đâu mà sai cái đó là lời gọi hàm mà.
  • Nhưng cái sai lớn nhất là: chuỗi chỉ có char* hoặc char[] chứ char*[] là thành mảng chuỗi rồi.
NBQ viết 18:28 ngày 01/10/2018
char *getFirstPt(char target, char *str[]){
  char p[100];
  int i, j;
  
  *str = &p[0];
for(i=0; *str[i] != '\0'; i++){
    if(*str == &target){
      return *str;
      break;
    }
  }
}

Mình thấy đoạn code của bạn có nhiều vấn đề lắm, trong hàm này bạn lại gán *str cho một địa chỉ trên stack chưa được gán giá trị gì là không có ý nghĩa, ngoài ra khi bạn return *tr rồi thì không cần break nữa.
Không nên sử dụng hàm scanf để nhập một chuỗi kí tự từ bàn phím, trong code của bạn sẽ không nhập vào được target, có thể dùng fgets để thay thế.

Có thể tham khảo đoạn code sau:

#include<stdio.h>
#include<stdlib.h>
char* getFirstPt(char target, char *str);

int main()
{
    char string[30];
    char kitu;

    printf("Nhap xau ki tu:");
    fgets(string, sizeof(string), stdin);

    printf("Nhap ki tu:");
    scanf("%c", &kitu);
    
    printf("%s", getFirstPt(kitu, string));

    return 0;
}

char *getFirstPt(char target, char *str)
{
    int i;

    for(i = 0; str[i] != '\0'; i++){
        if(str[i] == target){
            return (str + i);
        }
    }
}
nya nguyen viết 18:41 ngày 01/10/2018

Ồ, cảm ơn bạn nhé. Mà cho mình hỏi sao dùng scanf lại ko nhập được ký tự từ bàn phím vào?? Trước mình vẫn toàn dùng nó vì chưa được học fgets

nya nguyen viết 18:30 ngày 01/10/2018

Theo mình hiểu là char [] cũng là một dạng pointer nên ko thể dùng char *[] hả b?
Ông thầy giảng mình nghe câu được câu chăng, cứ bị ù ù cạc cạc

NBQ viết 18:34 ngày 01/10/2018

Hàm scanf có thể dùng để nhập kí tự được, nhưng mình nói là không nên dùng để nhập một chuỗi kí tự vì khi bạn nhập dấu cách nó sẽ kết thúc hàm scanf ngay, với code củ của bạn, comment hết những phần còn lại, chỉ để lại phần nhập chuỗi kí tự string, và kí tự target sẽ thấy kết quả ngay. Ngoài ra dùng hàm scanf để nhập chuỗi kí tự thì phải chỉ rõ kích thước chuỗi nhập vào, ví dụ scanf("%8s", string), nếu không rất dễ gặp lỗi buffer over flow.

NBQ viết 18:36 ngày 01/10/2018

Cái này @rogp10 đã trả lời bên trên rồi. char str[] là dùng cho một chuỗi kí tự, còn char *str[] là dùng cho một mảng chuỗi kí tự.

nya nguyen viết 18:31 ngày 01/10/2018

Chuỗi kí tự là “shduejwbdjfj” đúng ko bạn
Vậy còn mảng chuỗi kí tự là sao?
Có phải là như này ko bạn?
{(djdnfh),(djfjgkfk),(djfjfjfjf)}; ???

rogp10 viết 18:41 ngày 01/10/2018

Ừ bạn.

char* s[] = {"abc", "def", "ghi"};
Bài liên quan
0