scanf在空格C后拾取字符
我正在编写一个程序,它接受一行用户输入,并将数据存储在一个结构中,然后在链表中使用。数据以以下格式输入:命令\名称全名\地址帐户\余额scanf在空格C后拾取字符,c,string,scanf,C,String,Scanf,我正在编写一个程序,它接受一行用户输入,并将数据存储在一个结构中,然后在链表中使用。数据以以下格式输入:命令\名称全名\地址帐户\余额 command\u name调用该函数 full_name是一个带有破折号而不是空格的单个char数组 address是一个单独的char数组,其中包含街道、城市、州、邮政编码,所有字符都用逗号分隔 账户余额是双倍 我有一个函数,可以用空格替换'-'和'字符,使它们包含空格 我遇到的问题是,当我阅读地址时,状态被解读为状态,而zip被粘在一起。zip读取良好,所
command\u name
调用该函数
full_name
是一个带有破折号而不是空格的单个char
数组
address
是一个单独的char
数组,其中包含街道、城市、州、邮政编码,所有字符都用逗号分隔
账户余额
是双倍
我有一个函数,可以用空格替换'-'
和'
字符,使它们包含空格
我遇到的问题是,当我阅读地址时,状态被解读为状态,而zip被粘在一起。zip读取良好,所有其他输入读取良好。只有国家。它正慢慢地把我逼疯,所以我决定寻求帮助。我在下面附上了insert和print方法的代码以及一个结构的打印输出示例
Input: insert rick137 schwifty-ln,mango,nc,28105 2500
Sample output:
rick137
schwifty ln
mango, nc28105 28105
2500.00
Desired output:
rick137
schwifty ln
mango, nc 28105
2500.00
下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAME_LEN 40
#define ADDRESS_LEN 98
#define MENU_LEN 11
typedef struct customer {
char full_name[NAME_LEN+1];
char address[ADDRESS_LEN+1];
char street[55];
char city[32];
char state[2];
char zip[5];
double account_balance;
struct customer *next;
}customer;
customer *database = NULL;
int strcasecmp(const char *s1, const char *s2);
void rem_dash(char * str);
void rem_dash(char *str){
int i=0;
while(str[i]!='\0')
{
if(str[i]=='-')
{
str[i]=' ';
}
i++;
}
}
void rem_comma(char *str);
void rem_comma(char *str){
int i=0;
while(str[i]!='\0')
{
if(str[i]==',')
{
str[i]=' ';
}
i++;
}
}
void split_add(char *address, char *street, char *city, char *state, char *zip);
void split_add(char *address, char *street, char *city, char *state, char *zip){
rem_comma(address);
printf("%s\n", address);
sscanf(address, "%s %s %s %s", street, city, state, zip);
rem_dash(street);
rem_dash(city);
rem_dash(state);
rem_dash(zip);
}
void insert_customer(void);
void insert_customer(void){
customer *current, *prev, *new_customer;
new_customer = malloc(sizeof(struct customer));
current=NULL;
prev=NULL;
if(new_customer==NULL){
printf("Database full, cannot add more customers.\n");
return;
}
scanf("%40s %98s %lf", new_customer->full_name, new_customer->address, &new_customer->account_balance);
rem_dash(new_customer->full_name);
printf("%s\n", new_customer->full_name);
split_add(new_customer->address, new_customer->street, new_customer->city, new_customer->state, new_customer->zip);
//printf("%s\n%s, %s %s\n", new_customer->street, new_customer->city, new_customer->state, new_customer->zip);
current=database;
prev=NULL;
for (;current != NULL;prev = current, current = current->next){
if (current != NULL && strcmp(new_customer->full_name, current->full_name)==0) {
printf("DUPLICATE RECORD\n");
free(new_customer);
return;
}
}
current=database;
prev=NULL;
while(current != NULL && strcmp(current->full_name, new_customer->full_name)<0){
prev=current;
current=current->next;
}
new_customer->next=current;
if(prev==NULL){
database=new_customer;
}
else{
prev->next=new_customer;
}
printf("RECORD INSERTED\n");
}
void print_list(void);
void print_list(void){
customer *print;
for (print=database; print != NULL; print = print->next){
printf("%s\n%s\n%s, %2s %5s\n%9.2f\n-----\n", print->full_name, print->street, print->city, print->state, print->zip, print->account_balance);
}
}
#包括
#包括
#包括
#定义名称\u LEN 40
#定义地址\u LEN 98
#定义菜单11
类型定义结构客户{
字符全名[name_LEN+1];
字符地址[address_LEN+1];
查街[55];;
查尔城[32];
半焦态[2];
char-zip[5];
双倍账户余额;
结构客户*next;
}顾客;
客户*数据库=NULL;
int strcasecmp(常量字符*s1,常量字符*s2);
无效rem_破折号(字符*str);
无效rem_破折号(字符*str){
int i=0;
while(str[i]!='\0')
{
如果(str[i]='-')
{
str[i]='';
}
i++;
}
}
无效rem_逗号(char*str);
无效rem_逗号(char*str){
int i=0;
while(str[i]!='\0')
{
如果(str[i]==',')
{
str[i]='';
}
i++;
}
}
void split_add(字符*地址、字符*街道、字符*城市、字符*州、字符*邮政编码);
无效拆分添加(字符*地址、字符*街道、字符*城市、字符*州、字符*邮政编码){
rem_逗号(地址);
printf(“%s\n”,地址);
sscanf(地址,“%s%s%s%s”,街道、城市、州、邮编);
雷姆杜士(街);
雷姆·达什(城市);
rem_dash(州);
快速冲刺(zip);
}
无效插入客户(无效);
无效插入客户(无效){
客户*当前客户、*上一客户、*新客户;
新客户=malloc(sizeof(struct customer));
电流=零;
prev=NULL;
if(新客户==NULL){
printf(“数据库已满,无法添加更多客户。\n”);
返回;
}
scanf(“%40s%98s%lf”、新客户->全名、新客户->地址和新客户->账户余额);
rem\U dash(新客户->全名);
printf(“%s\n”,新客户->全名);
拆分添加(新客户->地址,新客户->街道,新客户->城市,新客户->州,新客户->邮政编码);
//printf(“%s\n%s,%s%s\n”,新客户->街道,新客户->城市,新客户->州,新客户->邮政编码);
当前=数据库;
prev=NULL;
对于(;当前!=NULL;上一个=当前,当前=当前->下一个){
if(当前!=NULL&&strcmp(新客户->全名,当前->全名)==0){
printf(“重复记录”);
免费(新客户);
返回;
}
}
当前=数据库;
prev=NULL;
while(current!=NULL&&strcmp(current->full\u name,new\u customer->full\u name)下一步;
}
新客户->下一个=当前;
if(prev==NULL){
数据库=新客户;
}
否则{
上一个->下一个=新客户;
}
printf(“插入的记录”);
}
作废打印清单(作废);
作废打印列表(作废){
客户*打印;
用于(打印=数据库;打印!=NULL;打印=打印->下一步){
printf(“%s\n%s\n%s,%2s%5s\n%9.2f\n----------\n”,打印->全名,打印->街道,打印->城市,打印->州,打印->邮政编码,打印->账户余额);
}
}
您的结构不允许有足够的空间容纳字符串终止符。状态
字段需要至少3个容量(两个字符加一个终止符),zip字段需要至少6个容量。其他字段可能需要更大的容量,也可能不需要
当您读入现有结构时,您超出了某些成员数组的边界,产生了未定义的行为。实际输出表明,
状态
字符串的终止符被zip
的第一个字符覆盖,但这是事后分析——您不能假设它会在所有情况下都是这样。一般来说,如果需要读取一行用户输入,那么就应该这样做!因此,使用fgets(或getline,如果允许的话),然后在该行上使用sscanf。此外,始终检查scanf调用的返回值以检测解析错误。