【发布时间】:2022-01-01 15:55:23
【问题描述】:
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define PATH "F:\\c\\projects\\Banking Management System\\data\\"
#define F_ACCT "accounts.txt"
#define FILENAME(file) PATH file
#define F_ACCT_FPRINTF "%05d%-8s%-30s%d%d%d%-20s%-20s%-20s%c%-15.2lf\n"
#define F_ACCT_FSCANF "%05d%8s%30[^\n]%d%d%d%20[^\n]%20[^\n]%20[^\n]%c%lf\n"
typedef struct Date
{
int dd;
int mm;
int ccyy;
} Date;
typedef struct Account
{
int id;
char acct_no[8];
char name[30];
Date birthday;
char telephone_no[20];
char mobile_no[20];
char tfn[20];
char acct_type; // 'S' - Saving | 'C' - Current | Fixed - 'F' | Recurring - 'R'
double acct_bal;
} Account;
int main(int argc, char *argv[])
{
Account *ac_t=malloc(sizeof(Account));
if (ac_t==NULL)
{
free(ac_t);
perror("Fatal error: ");
exit(EXIT_FAILURE);
}
FILE *fp=fopen(FILENAME(F_ACCT),"a+"); // Save option selected by the user
if (!fp) // NULL=0=true
{
free(ac_t);
perror("ERROR:");
exit(EXIT_FAILURE);
}
(fscanf(fp,F_ACCT_FSCANF,\
&ac_t->id,\
ac_t->acct_no,\
ac_t->name,\
&ac_t->birthday.dd,\
&ac_t->birthday.mm,\
&ac_t->birthday.ccyy,\
ac_t->telephone_no,\
ac_t->mobile_no,\
ac_t->tfn,\
&ac_t->acct_type,\
&ac_t->acct_bal));
printf("\ntmp=%d", tmp);
printf("\n[%d]",ac_t->id);
printf("\n[%s]",ac_t->acct_no);
printf("\n[%s]",ac_t->name);
printf("\n[%d]",ac_t->birthday.dd);
printf("\n[%d]",ac_t->birthday.mm);
printf("\n[%d]",ac_t->birthday.ccyy);
printf("\n[%s]",ac_t->telephone_no);
printf("\n[%s]",ac_t->mobile_no);
printf("\n[%s]",ac_t->tfn);
printf("\n[%c]",ac_t->acct_type);
printf("\n[%lf]",ac_t->acct_bal);
system("pause");
free(pw_t);
return 0;
}
================================================ ============================================
输入文件(accounts.txt) ==========================
000011000 Anil Dhar 27111960(02) 8883 2827 0408 942 407 111222333 S 100.21
Note: The record was created successfully using frpintf() as per F_ACCT_FPRINTF.
**Problem**
=======
fscanf is reading garbage values like this:
ac_t->id 1
t_acct_no
name Anil Dhar
birthday.dd 27
birthday.mm 11
birthday.ccyy 1960
telephone_no (02) 8883 2827 0408 942 407 111222333 Sogram Files\Intel\ip¬tαK4
mobile_no 0408 942 407 111222333 Sogram Files\Intel\ip¬tαK4
tfn 111222333 Sogram Files\Intel\ip¬tαK4
t_acct_type
acct_bal 74895632819821970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
我的所有字符串变量,如 name、telephone_no、mobile_no、tfn 都可以包含空格。 记录没有被任何东西划界。无论我在哪里读取字符串变量,我的 fscanf() 都没有正确填充字段。
可能出了什么问题????
【问题讨论】:
-
更正:#define F_ACCT_FSCANF "%05d%8[^\n]%30[^\n]%02d%02d%04d%20[^\n]%20[^\n] %20[^\n]%c%15.2lf\n"
-
使用
fscanf读取这种数据是一个可怕的想法,但你的直接问题是字符缓冲区溢出。char name[30];只能包含一个最大长度为 29 的字符串,因为每个字符串都有一个空分隔符,但您试图在其中填充一个长度为 30 的字符串。与所有其他char [...]字段相同。 -
%20[^\n]一直读到换行符,所以它读到 everything 直到行尾。在你的情况下,看起来字段是用空格分隔的。输入格式是什么? -
输入格式为 F_ACCT_FPRINTF
-
@KamilCuk 输入格式在 F_ACCT_PRINTF 中定义为预处理器指令。谢谢
标签: gcc scanf codeblocks