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调用的返回值以检测解析错误。