scanf在空格C之后拾取字符

时间:2017-12-07 20:05:03

标签: c string scanf

我正在编写一个程序,它接受一行用户输入并将数据存储在一个结构中,然后在链表中使用。数据以下列格式输入:command_name full_name address account_balance

command_name调用该函数;

full_name是一个char数组,带有短划线而非空格。

address是一个char数组,其中街道,城市,州,拉链均以逗号分隔

account_balancedouble

我有一个函数用空格替换'-'','字符,因此它们包含空格。

我遇到的问题是,当我读取地址时,状态被读取为状态和zip卡在一起。拉链读得很好,所有其他输入都可以正常读取。只是国家。它正在慢慢地让我陷入疯狂,所以我决定寻求帮助。我已经附上了下面的插入和打印方法的代码以及结构的打印输出示例。

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);
    }
}

1 个答案:

答案 0 :(得分:1)

您的struct不允许字符串终结符有足够的空间。 state字段需要至少3个容量(两个字符加一个终结符),而zip字段需要至少为6的容量。您可能想要或不想要更大容量用于其他字段。

当您读入现有结构时,会超出某些成员数组的边界,从而产生未定义的行为。实际输出表明state字符串的终结符被zip的第一个字符覆盖,但这是 post hoc 分析 - 你不能认为它在所有情况下都会这样。