扫描c中循环内带空格的字符串并创建一个完美的表格

时间:2016-10-09 07:04:32

标签: c string loops

当我输入空白空间的设备名称时,它将退出。我尝试将其更改为fget然后在下一个循环时它将跳过"输入设备名称。我也试过"%[^ \ n] s"它也做同样的事情。

#include <stdio.h>
#include <stdlib.h>

struct deviceType
{
    char cName[20];
    float fPrice;
    int iQty;
    float fTotal;
};
void fnKeyIn(float*,int*);
float fnCalcTotal(const float,int);
void fnGetDiscount (const float,double*);
float fnAfterDiscount(const float,double);
void fnPrint(struct deviceType ,double,const float);

int main()
{
    struct deviceType asEntertaiment[50] ;
    char ans;
    int n,i=0;
    double afDiscount[i];
    float afAfterDiscount[i];
    float full = 0;

    do{
        printf("\nEnter device name: ");
        //gets(asEntertaiment[i].cName);
        scanf("%s",asEntertaiment[i].cName);
        getchar();

        fnKeyIn(&asEntertaiment[i].fPrice,&asEntertaiment[i].iQty);

        printf("\nDo you want to add more?\n");scanf("%s",&ans);

        i++;n=i;

    }while((ans=='Y')||(ans=='y'));

  printf("\nDevices         Price  Quantity  Total  Discount After Discount\n");

        for(i=0;i<n;i++)
        {
            asEntertaiment[i].fTotal = fnCalcTotal(asEntertaiment[i].fPrice,asEntertaiment[i].iQty);

            if(asEntertaiment[i].iQty>=50)
                {
                    fnGetDiscount (asEntertaiment[i].fTotal,&afDiscount[i]);
                }
            else
                {
                    afDiscount[i]= 0;
                }

            afAfterDiscount[i] = fnAfterDiscount(asEntertaiment[i].fTotal,afDiscount[i]);
            full=full + afAfterDiscount[i];
            fnPrint(asEntertaiment[i],afDiscount[i],afAfterDiscount[i]);

        }

    printf("\nTotal amount payable: %3.2f",full);

    return 0;
}
    void fnKeyIn(float *price,int *quantity)
        {
            printf("\nEnter device price: RM ");
            scanf("%f",price);

            printf("\nEnter quantity ordered: ");
            scanf("%d",quantity);
        }
    float fnCalcTotal(const float Price,int Qty)
        {
            return(Price*Qty);
        }
    void fnGetDiscount (const float Total,double *Discount)
        {
            *Discount=Total*0.1;
        }
    float fnAfterDiscount(const float Total,double Discount)
        {
            return(Total-Discount);
        }
    void fnPrint(struct deviceType E,double Discount,const float After)
        {
            printf("\n%s %3.2f    %d      %3.2f   %3.2lf       %3.2f    ",E.cName,E.fPrice,E.iQty,E.fTotal,Discount,After);
        }

1 个答案:

答案 0 :(得分:0)

scanf()函数会在输入流中留下它不想要的任何字符,在您的情况下,这意味着用户在第一个单词后输入的任何字符仍在输入流中。您可以丢弃这些字符:

printf("\nEnter device name: ");
//gets(asEntertaiment[i].cName);
scanf("%s",asEntertaiment[i].cName);
while (getchar() != '\n')
    continue;              // discard extra characters

如果你真的想覆盖你的基地,你可以改为:

int ch;
while((ch = getchar()) != '\n' && ch != EOF)
    continue;

如果您要测试int,则必须使用EOF或有符号整数类型:char是无符号的。

要获得多个单词的输入,请尝试使用fgets()读取第一个换行符前的字符或最大字符数,以先到者为准:

printf("\nEnter device name: ");
//gets(asEntertaiment[i].cName);
fgets(asEntertaiment[i].cName, 50, stdin);
int find = 0;
while (find < 49 && (asEntertaiment[i].cName)[find] != '\n')
    ++find;
if (find == 49) {
    while (getchar() != '\n')
        continue;              // discard extra characters
    }
(asEntertaiment[i].cName)[find] = '\0';

如果用户输入的设备名称长度超过49个字符(49个字符+'\ 0'),您仍需要清除额外字符的输入流。调用fgets()后,这些额外字符仍在输入流中。这将按原样工作,但最好编写一个函数来处理此输入,并在需要时进行清理调用。

你应该记住,如果你不在它们之后进行清理,一些输入函数会在输入流中留下等待下一个输入函数的字符。此外,您应该真正验证您的输入。如果用户在“输入设备价格:”提示下输入字符串而不是数字,则程序会变得疯狂。 scanf()会返回int,即成功分配的数量。因此,如果您要求int,并且用户输入字符串,则返回值为0.您可以使用它来测试用户的输入,并循环以在输入不正确时再次输入它们。