2012-11-06 31 views
5

Tại sao mã này không hoạt động. Chỉ cần cố gắng để kiểm tra xem người dùng nhập vào là giống như một mật khẩustrcmp với con trỏ không hoạt động trong C

char *pass; 

printf("Write the password: "); 
scanf("%s", pass); // Because is a pointer the & is out ? 


if(strcmp(pass , "acopio") == 0) 
+4

Tại sao -1? Tôi đang học; cố gắng tìm câu trả lời ở đây; và đối với người mới bắt đầu, không dễ hiểu các câu trả lời khác. – jotape

Trả lời

8

Bạn chưa thực sự phân bổ bất kỳ không gian nào để đặt dữ liệu. Định nghĩa một con trỏ chỉ định nghĩa một biến có thể chứa địa chỉ của một khối dữ liệu, nó không phân bổ khối.

Bạn có một vài tùy chọn, cấp phát bộ nhớ động ra khỏi heap để ghi vào và làm cho con trỏ trỏ đến nó. Hoặc sử dụng bộ nhớ được cấp phát tĩnh trên ngăn xếp và chuyển địa chỉ của nó tới các cuộc gọi của bạn. Có rất ít lợi ích cho bộ nhớ động trong trường hợp này (vì nó tạm thời được sử dụng và nhỏ). Bạn sẽ có nhiều việc phải làm nếu bạn sử dụng bộ nhớ động - bạn phải đảm bảo bạn có được những gì bạn đã yêu cầu khi phân bổ nó và đảm bảo bạn đã trả lại khi bạn hoàn thành và đảm bảo bạn không sử dụng nó sau khi bạn đã đưa nó trở lại (khó khăn trong một ứng dụng lớn, tin tưởng tôi!) Nó chỉ là công việc nhiều hơn, và bạn dường như không cần thêm nỗ lực đó.

Các ví dụ bên dưới cũng sẽ cần kiểm tra lỗi đáng kể, nhưng cung cấp cho bạn ý tưởng chung.

ví dụ:

char *pass = malloc (SOMESIZE); 

printf("Write the password: "); 
scanf("%s", pass); 


if(strcmp(pass , "acopio") == 0) 

hoặc

char pass[SOMESIZE]; 

printf("Write the password: "); 
scanf("%s", pass); 


if(strcmp(pass , "acopio") == 0) 
+0

rất rõ ràng. Bạn quên & trong scanf tùy chọn thứ 2. Đã không nhận được lý do tại sao tốt hơn để sử dụng bộ nhớ động (heap) hơn bộ nhớ tĩnh (stack). Cái nào nhỏ hơn? – jotape

+3

Bạn không cần ký hiệu cho cuộc gọi scanf vì tham chiếu tới mảng không có chỉ mục * là * địa chỉ, tức là pass == & pass [0] – Joe

+0

@Joe ví dụ, không phải là/grammer-nazi – Anthony

3

pass là một con trỏ unitialized, và bạn cố gắng để viết vào đó. Bạn phải phân bổ đủ bộ nhớ để giữ một chuỗi. Ví dụ: char pass[SIZE] sẽ hoạt động tốt hơn.

+0

Vì vậy, tôi không phải sử dụng một con trỏ; chỉ là một mảng của char? – jotape

+1

Thật vậy. Lưu ý bạn cũng có thể sử dụng phân bổ động (với một con trỏ đến 'char'), nhưng nó là vô ích ở đây. – md5

1

Bạn cần phân bổ pass để scanf sẽ có một nơi để lưu trữ đầu vào. Nếu không, bạn có tham nhũng bộ nhớ.

0

Có con trỏ không được khởi tạo. Nếu bạn gỡ lỗi nó, bạn sẽ nhận được một access violation or segmentation fault. Mã có thể được thay đổi như sau.

char pass[22];//22 can be replaced with other number 

    printf("Write the password: "); 
    scanf("%s", pass); 
    if(strcmp(pass , "acopio") == 0) 
    printf("fu");//just to check 
+0

@Daveshaw: I muốn đăng bài tương tự, nhưng stackoverflow sẽ không cho phép tôi lưu các chỉnh sửa <6 ký tự thay đổi: D – anishsane

0

Bạn chưa khởi tạo pass để trỏ đến bộ đệm hoặc vị trí khác để lưu trữ đầu vào.

Đối với một cái gì đó đơn giản như thế này, bạn có thể khai pass như một mảng của char thay vì một con trỏ:

char pass[N]; // where N is large enough to hold the password plus a 0 terminator 

scanf("%s", pass); 
if (strcmp(pass, "acopio") == 0) 
{ 
    ... 
} 

Trừ khi nó là toán hạng của sizeof, _Alignof, hoặc unary & nhà khai thác, hoặc là một chuỗi ký tự được sử dụng để khởi tạo mảng khác trong khai báo, biểu thức thuộc loại "phần tử N số T" sẽ được chuyển đổi ("phân rã") thành biểu thức loại "con trỏ đến T" và giá trị của biểu thức sẽ là địa chỉ của yếu tố đầu tiên của mảng.

Khi bạn vượt qua pass như một cuộc tranh cãi để scanfstrcmp, kiểu của biểu thức pass được chuyển đổi từ "mảng N phần tử của char" thành "con trỏ đến char", và giá trị của biểu thức là địa chỉ của phần tử đầu tiên là pass hoặc &pass[0].Đó là lý do tại sao bạn không cần sử dụng toán tử & trong cuộc gọi scanf.

Tương tự như vậy, trong strcmp cuộc gọi, chuỗi chữ "acopio" được chuyển đổi từ một biểu hiện của "mảng phần tử 7 của char" loại (const char trong C++) để "con trỏ đến char".

0
#include<stdio.h> 
main() 
{ 
    int mystrcmp(char *,char *); 

    char s1[100],s2[100]; 
    char *p1,*p2; 
    p1=s1; 
    p2=s2; 
    printf("Enter the first string..?\n"); 
    scanf("%s",p1); 
    printf("Enter the second string..?\n"); 
    scanf("%s",p2); 
    int x=mystrcmp(p1,p2); 
    if(x==0) 
     printf("Strings are same\n"); 
    else 
     printf("Strings are not same..\n"); 


} 
int mystrcmp(char *p1,char *p2) 
{ 
    while(*p1==*p2) 
    { 
     if(*p1=='\0' || *p2=='\0') 
      break; 
     p1++; 
     p2++; 
    } 
    if(*p1=='\0' &&as *p2=='\0') 
     return(0); 
    else 
     return(1); 
} 

mã đơn giản cho người mới bắt đầu ....

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