我试图为登录程序编写代码,我必须使用 C 结构才能完成它。现在代码可以编译,但当用户输入用户名和密码时,我收到Segmentation error: 11
。
附加说明:代码在linux和windows上运行良好,但在unix环境下出现段错误。到目前为止我已经写了这个:
typedef struct {
char username[20], password[20];
} DATA;
DATA user[10];
char iusername[20], ipassword[20];
DATA saveToStructforlogin(char* str) {
DATA res;
int flag = 0;
int size;
char *token = strtok(str, ";");
while (token != NULL) {
if (0 == flag) {
strcpy(res.username, token);
} else {
strcpy(res.password, token);
}
flag++;
token = strtok( NULL, ";" );
}
return res;
}
char *getUsername(DATA* arr, int size) {
int i;
for (i = 0; i < size; i++) {
return arr[i].username;
}
return 0;
}
char *getPassword(DATA* arr, int size) {
int i;
for (i = 0; i < size; i++) {
return arr[i].password;
}
return 0;
}
char *trimwhitespace(char *str) {
char *end;
// Trim leading space
while (isspace((unsigned char)*str))
str++;
if (*str == 0) // All spaces?
return str;
// Trim trailing space
end = str + strlen(str) - 1;
while (end > str && isspace((unsigned char)*end))
end--;
*(end+1) = 0;
return str;
}
int main() {
FILE *fp;
char buffer[BUFFER_SIZE];
int i = 0, flag = 0, a, status = 0;
DATA arr[10];
char *mUsername[10];
char *mPassword[10];
fp = fopen("admin.txt", "r");
if (!fp) {
return -1;
}
printf("Admin Login\n");
printf("Username: ");
scanf("%s", iusername);
printf("Password: ");
scanf("%s", ipassword);
while (fgets(buffer, BUFFER_SIZE, fp)) {
arr[flag] = saveToStructforlogin(buffer);
mUsername[flag] = getUsername(arr, flag);
mPassword[flag] = getPassword(arr, flag);
if (strcmp(trimwhitespace(mUsername[flag]), iusername) == 0 &&
strcmp(trimwhitespace(mPassword[flag]), ipassword) == 0) {
status = 1;
break;
}
flag++;
}
if (status == 1) {
printf("Welcome to Admin Dashboard \n");
} else {
printf("Username or Password was wrong. please try again \n");
main();
}
fclose(fp);
return 0;
}
最佳答案
您的程序有多个问题:
函数
getUsername
和getPassword
仅返回数组的第一个条目,如果为空则返回NULL。检查用户名和密码的循环太复杂。
这是一个更简单的版本:
while (fgets(buffer, BUFFER_SIZE, fp)) { DATA user = saveToStructforlogin(buffer); if (strcmp(user.username, iusername) == 0 && strcmp(user.password, ipassword) == 0) { status = 1; break; } }
函数
saveToStructforlogin
应该修剪文件中的字符串:DATA saveToStructforlogin(char* str) { DATA res = { 0 }; char *token = strtok(str, ";"); if (token != NULL) { strcpy(res.username, trimwhitespace(token)); token = strtok(NULL, ";"); if (token != NULL) { strcpy(res.password, trimwhitespace(token)); } } return res; }
递归调用 main 是不正确的。您应该使用
for(;;)
循环。返回结构是合法的,但不是一个很好的 API:它不允许正确的错误检测。
这是代码的简化和更正版本:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char username[20], password[20];
} DATA;
char iusername[20], ipassword[20];
char *trimwhitespace(char *str) {
char *end = str + strlen(str);
// Trim trailing space
while (end > str && isspace((unsigned char)end[-1])) {
*--end = '\0';
}
// Trim leading space
while (isspace((unsigned char)*str)) {
str++;
}
return str;
}
size_t bstrcpy(char *dest, size_t size, const char *src) {
size_t len = strlen(src);
if (len < size) {
memcpy(dest, src, len + 1);
} else
if (size > 0) {
memcpy(dest, src, size - 1);
dest[size - 1] = '\0';
}
return len;
}
DATA *saveToStructforlogin(DATA *res, char* str) {
char *token = strtok(str, ";");
if (token != NULL) {
bstrcpy(res->username, sizeof(res->username), trimwhitespace(token));
token = strtok(NULL, ";");
if (token != NULL) {
bstrcpy(res->password, sizeof(res->password), trimwhitespace(token));
return res;
}
}
return NULL;
}
int main(void) {
char buffer[1024];
FILE *fp;
int status;
fp = fopen("admin.txt", "r");
if (!fp) {
return 1;
}
for (;;) {
printf("Admin Login\n");
printf("Username: ");
if (scanf("%s", iusername) != 1)
break;
printf("Password: ");
if (scanf("%s", ipassword) != 1)
break;
status = 0;
rewind(fp);
while (fgets(buffer, sizeof(buffer), fp)) {
DATA user;
if (saveToStructforlogin(&user, buffer)
&& !strcmp(user.username, iusername)
&& !strcmp(user.password, ipassword)) {
status = 1;
break;
}
}
if (status == 0) {
printf("Username or Password was wrong, please try again\n");
continue;
}
printf("Welcome to Admin Dashboard \n");
// handle the session here.
break;
}
fclose(fp);
return 0;
}
关于c - 段错误: 11 (C programming),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44871493/