首页 > 解决方案 > 要求输入全部而不是单独输入

问题描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include <time.h>

struct customer
{
    char name[45];
    char invoice[4];
    char service[2];
    char carNo[16];
    char fee[3];
    bool urgent;
    time_t date;
};

/*********************************************************************************************/
void toFile(char*); // will pass string (char*) to it and itll write it to record.txt - DONE
void displayMenu(void);      // will display the menu  - DONE
void newInvoice(int invoiceNo);
/*********************************************************************************************/
int main()
{
    char toContinue;
    int invoiceNo =1;
    // format of invoices in txt file
    do
    {
        newInvoice(invoiceNo);
        invoiceNo += 1;
        // asking if user wants to continue to another order or close the program
        printf("Do you want to continue?  (Y or N) :");
        scanf(" %c",&toContinue);
    }
    while (toContinue !='N' && toContinue !='n');
    return 0;
}
/*********************************************************************************************/
void newInvoice(int invoiceNo)
{
    // variable declaration
    char enter,urgentCH;
    int feeINT;
    struct customer *newCus;
    newCus = (struct customer*) malloc ( sizeof(struct customer));
    displayMenu();
    enter = fgetc(stdin);
        sprintf(newCus->invoice, "%d", invoiceNo);
        // customer info being collected
        printf("Customer Name:\n");
        scanf("%[^\n]%*c", newCus->name);
    
        printf("Vehicle Numb :\n");
        scanf("%[^\n]%*c", newCus->carNo);
    
        printf("Service Selection Numb (From Menu):\n");
        scanf("%[^\n]%*c", newCus->service);
    
        printf("Urgent? (Y or N ):\n");
        scanf(" %c",&urgentCH);
        
        if(urgentCH == 'Y' || urgentCH == 'y')
            newCus->urgent = true;
        else
            newCus->urgent = false;
        
        printf("Fee (from menu):");
        scanf("%d",&feeINT);
        sprintf(newCus->fee, "%d", feeINT);
        time(&newCus->date); // system date and time being taken
        
        // writng to file
        toFile("Invoice:\t");
        toFile(newCus->invoice);
        toFile("  customer: ");
        toFile(newCus->name);
        toFile("  vehicle: ");
        toFile(newCus->carNo);
        toFile("  service: ");
        toFile(newCus->service);
        toFile("  type: ");
        if(newCus->urgent)
            toFile("urgent");
        else
            toFile("normal");
        toFile("  fee: ");
        toFile(newCus->fee);
        toFile("  date: ");
        toFile(ctime(&newCus->date));
        // invoice output
        printf("Customer:%s\n  vehicle:%s\n  Service:%s\n  type:%s\n  Fee:%s\n  Date:%s\n",
        newCus->name,newCus->carNo,newCus->service,newCus->urgent?"urgent":"normal",newCus->fee,ctime(&newCus->date));
    free(newCus);
}


/*********************************************************************************************/
void displayMenu()
{
    printf("Numb      Service type                           Time           service fee\n");
    printf("                                         (minutes)      Normal   Urgent\n");
    printf("1       Repair punctured car tyre/piece         10             5        6\n");
    printf("2       Car tyre change /piece                  15           150      160\n");
    printf("3       Mineral Oil Change                      20            80       90\n");
    printf("4       Synthetic Oil Change                    10           130      140\n");
    printf("5       Battery Change                           5           200      210\n");
    printf("6       Head light bulb change /piece            5             6        8\n");
    printf("7       Taillight bulb change /piece             5             6        8\n");
    printf("8       Car Wash                                10            10       12\n");
    printf("------------PRESS ANYTHING TO CONTINUE------------\n");
}
/*********************************************************************************************/
void toFile(char* Str2Write)
{
    // file opened for writing
    FILE *file2write;
    file2write = fopen("file.txt","a");
    // file opened successfully check
    if(file2write == NULL)
        exit(1);
    // writng
    fprintf(file2write,"%s",Str2Write);
    // fprintf(fptr,"\n");
    // closing
    fclose(file2write);
}
/*********************************************************************************************/

问题出在

void newInvoice(int invoiceNo)
{
    // variable declaration
    char enter,urgentCH;
    int feeINT;
    struct customer *newCus;
    newCus = (struct customer*) malloc ( sizeof(struct customer));
    displayMenu();
    enter = fgetc(stdin);
        sprintf(newCus->invoice, "%d", invoiceNo);
        // customer info being collected
        printf("Customer Name:\n");
        scanf("%[^\n]%*c", newCus->name);

        printf("Vehicle Numb :\n");
        scanf("%[^\n]%*c", newCus->carNo);

        printf("Service Selection Numb (From Menu):\n");
        scanf("%[^\n]%*c", newCus->service);

        printf("Urgent? (Y or N ):\n");
        scanf(" %c",&urgentCH);

        if(urgentCH == 'Y' || urgentCH == 'y')
            newCus->urgent = true;
        else
            newCus->urgent = false;

        printf("Fee (from menu):");
        scanf("%d",&feeINT);
        sprintf(newCus->fee, "%d", feeINT);
        time(&newCus->date); // system date and time being taken

这部分给出了一个奇怪的输出:

输出在这里

我对此很陌生。有人告诉我这scanf是一个危险的命令,但我不知道如何用其他东西替换它。

标签: cdebugginginputscanfstdin

解决方案


你是对的,你可能不应该使用scanf,而是使用fgets.

尝试构建此代码示例:

void newInvoice(int invoiceNo)
{
    // Input Variable
    char userInput[100];

    // You make this not a pointer since in 
    // original code you don't return it anywhere
    // and you don't have to deal with managing memory leaks that you were having.
    Customer newCustomer;

    // COPY PASTE THIS FROM HERE
    printf("Customer Name: "); // query for user input 
    fgets(userInput, sizeof(userInput), stdin); // get the input
    userInput[strlen(userInput) - 1] = '\0'; // removes the \n at end when the user press enter
    strcpy(newCustomer.name, userInput); // copy userInput into struct
    // TO HERE 

    printf("You Inputted: %s\n", userInput);

    // add more options here
}

运行它的示例输出应该是:

Customer Name: David
You Inputted: David
Do you want to continue?  (Y or N) :n

还使用以下定义:

typedef struct customer
{
    char name[45];
    char invoice[4];
    char service[2];
    char carNo[16];
    char fee[3];
    bool urgent;
    time_t date;
}Customer;

所以你不必struct customer每次都说。只是让你的代码看起来更干净。


推荐阅读