C语言银行管理程序报错:无法将char**转换为char*的求助
Hey there! Let's walk through fixing the error you're facing, plus a few other small issues in your code to get it running smoothly.
1. The Core Error: char** to char* Mismatch
The error cannot convert 'char**' to 'char*' for argument '1' to 'char* strcpy(char*, const char*)' comes from how you defined the name field in your bank struct:
typedef struct bank { char *name[NAME_LEN]; // ❌ This is an array of char pointers (char**) // ... rest of the struct } bank;
When you call strcpy(t->name, name), t->name is the name of an array of pointers, which decays to a char** type. But strcpy expects its first argument to be a char* (a pointer to a character array where it can copy the string).
Fix: Change the name field to a character array instead:
typedef struct bank { char name[NAME_LEN]; // ✅ This is a char array (decays to char*) int id; int money; struct bank *next; } bank;
This way, t->name is a valid char* pointer that strcpy can use.
2. Other Fixes for Syntax & Logic Issues
Let's address a few other bugs that would cause your program to crash or behave incorrectly:
a. Syntax Error in WithDraw Function
You missed a comparison operator in the balance check:
// ❌ Original broken line if (t->money { // ✅ Fixed version if (t->money < money) {
b. Linked List Insertion Logic in ReadAccount
Your insertion order was reversed, which would break the linked list:
// ❌ Original // t->next = head->next; // head->next = t; // ✅ Fixed order t->next = head->next; // Point new node to the first existing node head->next = t; // Update head to point to the new node
c. File Write Cleanup in WriteAccount
When using rewind(fp) and writing, old content longer than the new data will remain in the file. Add code to truncate the file before writing to avoid leftover data:
void WriteAccount(FILE *fp) { bank *t; rewind(fp); // Truncate the file to 0 size to remove old content ftruncate(fileno(fp), 0); // Add this line (needs #include <unistd.h>) for (t = head->next; t != tail; t = t->next) { fprintf(fp, "%d %s %d\n", t->id, t->name, t->money); } }
Don't forget to add #include <unistd.h> at the top for ftruncate and fileno.
Fixed Complete Code
Here's the full corrected code with all the fixes applied:
#define NAME_LEN 20 #include "stdio.h" #include "stdlib.h" #include "string.h" #include <unistd.h> // Added for ftruncate and fileno #pragma warning(disable:4996) typedef struct bank { char name[NAME_LEN]; // Fixed: char array instead of pointer array int id; int money; struct bank *next; } bank; bank *head, *tail; void Init_account(FILE *fp); void Make_account(FILE *fp); void Deposit(FILE *fp); void WithDraw(FILE *fp); void WriteAccount(FILE *fp); void Account_inquire(void); void ReadAccount(int id, char *name, int money); void Init_account(FILE *fp) { int id; char name[NAME_LEN]; int money; head = (bank *)malloc(sizeof(bank)); tail = (bank *)malloc(sizeof(bank)); head->next = tail; tail->next = tail; while (fscanf(fp, "%d %s %d", &id, name, &money) == 3){ ReadAccount(id, name, money); } } void ReadAccount(int id, char *name, int money) { bank *t; t = (bank *)malloc(sizeof(bank)); t->id = id; strcpy(t->name, name); t->money = money; // Fixed insertion order t->next = head->next; head->next = t; } void Make_account(FILE *fp) { int id; char name[NAME_LEN]; int money; bank *t; t = (bank *)malloc(sizeof(bank)); printf("\n*********계좌 생성*********\n"); printf("계좌번호 : "); scanf("%d", &id); printf("예 금 주 : "); scanf("%s", name); printf("입 금 액 : "); scanf("%d", &money); t->id = id; strcpy(t->name, name); t->money = money; t->next = head->next; head->next = t; WriteAccount(fp); } void Deposit(FILE *fp) { int id; int money; bank *t; printf("계좌번호 : "); scanf("%d", &id); printf("입 금 액 : "); scanf("%d", &money); for (t = head->next; t != tail; t = t->next) { if (t->id == id) { t->money += money; WriteAccount(fp); return; } } printf("없는 계좌번호입니다.\n"); } void WithDraw(FILE *fp) { int id; int money; bank *t; printf("계좌번호 : "); scanf("%d", &id); printf("출 금 액 : "); scanf("%d", &money); for (t = head->next; t != tail; t = t->next) { if (t->id == id) { // Fixed balance check syntax if (t->money < money) { printf("출금액이 잔액을 초과할 수 없습니다.\n"); return; } else { t->money -= money; } WriteAccount(fp); return; } } printf("없는 계좌번호입니다.\n"); } void Account_inquire(void) { bank *t; for (t = head->next; t != tail; t = t->next) { printf("\n*********잔액 조회*********\n"); printf("계좌번호 : %d\n", t->id); printf("예 금 주 : %s님\n", t->name); printf("잔 액 : %d원\n\n", t->money); } } void WriteAccount(FILE *fp) { bank *t; rewind(fp); // Truncate file to remove old content before writing ftruncate(fileno(fp), 0); for (t = head->next; t != tail; t = t->next) { fprintf(fp, "%d %s %d\n", t->id, t->name, t->money); } } int main() { int input; FILE *fp; fp = fopen("data.txt", "r+"); if (fp == NULL) { // Handle case where file doesn't exist fp = fopen("data.txt", "w+"); } Init_account(fp); do { printf("계좌 생성&관리 프로그램입니다. 원하시는 번호를 입력하세요.\n"); printf("*********************************************\n"); printf("1)계좌 생성 2)계좌 조회 3)입금 4)출금 5)종료\n"); printf("*********************************************\n"); printf("입력 >"); scanf("%d", &input); switch (input){ case 1: Make_account(fp); break; case 2: Account_inquire(); break; case 3: Deposit(fp); break; case 4: WithDraw(fp); break; case 5: input = 0; free(head); free(tail); break; default: printf("잘못 입력하셨습니다. \n"); break; // Removed recursive main call to avoid stack overflow } } while (input != 0); fclose(fp); // Don't forget to close the file! return 0; }
I also added a few extra improvements:
- File existence check in
main()(creates the file if it doesn't exist) - Closed the file in
main()to avoid resource leaks - Removed the recursive call to
main()in the default case (this could cause stack overflow with repeated bad inputs)
内容的提问来源于stack exchange,提问作者Rozwel Gustab

