【问题标题】:C program cashier systemC程序收银系统
【发布时间】:2017-04-03 00:59:24
【问题描述】:

嗯,我只学了 2 个月的 C 编程。我在这里得到的代码是解决收银员系统的问题。我得到了一些条形码编号、商品名称和价格。收银员输入多个条形码并以 F 结束后,应显示带有项目编号、代码和价格的收据。 这些是我编译的代码。但是,我只能输入一个条形码,程序就崩溃了。

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

int main()
{
typedef struct goods
{
    char goods_code[6];
    char goods_descrip[20];
    float price;
}goodtype;

goodtype goods[13];
strcpy(goods[0].goods_descrip, "Chicken");
strcpy(goods[0].goods_code, "00310");
goods[0].price = 35.00;

strcpy(goods[1].goods_descrip, "Pork");
strcpy(goods[1].goods_code, "00311");
goods[1].price = 20.50;

strcpy(goods[2].goods_descrip, "Beef");
strcpy(goods[2].goods_code, "00322");
goods[2].price = 45.00;

strcpy(goods[3].goods_descrip, "Fish");
strcpy(goods[3].goods_code, "00323");
goods[3].price = 40.00;

strcpy(goods[4].goods_descrip, "Walmart T Shirt");
strcpy(goods[4].goods_code, "00510");
goods[4].price = 75.00;

strcpy(goods[5].goods_descrip, "Walmart Trousers");
strcpy(goods[5].goods_code, "00511");
goods[5].price = 120.00;

strcpy(goods[6].goods_descrip, "Walmart Coat");
strcpy(goods[6].goods_code, "00512");
goods[6].price = 100.00;

strcpy(goods[7].goods_descrip, "Walmart Jumper");
strcpy(goods[7].goods_code, "00513");
goods[7].price = 85.00;

strcpy(goods[8].goods_descrip, "Mug");
strcpy(goods[8].goods_code, "00710");
goods[8].price = 15.50;

strcpy(goods[9].goods_descrip, "Fry Pan");
strcpy(goods[9].goods_code, "00711");
goods[9].price = 200.00;

strcpy(goods[10].goods_descrip, "Bowl");
strcpy(goods[10].goods_code, "00712");
goods[10].price = 25.00;

strcpy(goods[11].goods_descrip, "Dish");
strcpy(goods[11].goods_code, "00713");
goods[11].price = 25.00;

char tempCode[6];
char receiptNM[20], receiptCD[6];
char stop[2] = {"F"};
float receiptPC, ttlcost = 0;
unsigned int i;

printf("Please enter the item code. Type F to finish");
scanf("%s", &tempCode);

while ( strcmp(tempCode, stop) ){
    for (i = 0; i <= 12; ++i){
        if (strcmp(tempCode, goods[i].goods_code) == 0){
            strcpy(receiptNM, goods[i].goods_descrip);
            strcpy(receiptCD, goods[i].goods_code);
            receiptPC = goods[i].price;
            ttlcost += goods[i].price;
        }
        else{
            printf("This item code does not exist! Try again!\n");
    }
printf("Please enter the item code. Type F to finish");
scanf("%s", &tempCode);
}
printf("_____________________________________\n\n");
printf("      THANK YOU FOR VISITING US!     \n");
printf("_____________________________________\n");
printf("         Here is your receipt:       \n\n");
printf("%10s%20s%10s", "Item", "Code", "Price");
printf("%10s%20s%10.2f\n", receiptNM, receiptCD, receiptPC);
printf("\n_____________________________________\n");
printf("          TOTAL COST:%.2f            \n", ttlcost);
}

我为此苦苦挣扎了好几个小时,无法解决。 示例输出应为Sample receipt

当我输入 00310 时,程序无法识别它。当我输入 310 时,它可以。

此外,当键入的代码不存在时,错误消息应该只显示一次。但在我的程序中,它执行了 12 次。

【问题讨论】:

  • scanf("%c", &amp;tempCode); 扫描单个字符,而不是字符串。也就是说,tempCode 不会是一个以 NUL 结尾的字符串。所以你不能在上面使用任何字符串函数。
  • 你的输出是什么,你预计会怎样解释这一点。 @Sam.W
  • 另外,建议您学习使用调试器(如果您还没有)。这将为您节省大量时间。
  • 编译时包含所有警告和调试信息(例如,如果使用 GCC,则为 gcc -Wall -Wextra -g)。改进代码,直到您没有收到任何警告。了解如何使用调试器 (gdb)。 阅读documentation

标签: c checkout


【解决方案1】:

这里

for (i = 0; i <= 12; ++i){
    if (strcmp(tempCode, goods[i].goods_code) == 0){

您正在访问上次迭代中未初始化的值(未定义的行为),因为您刚刚从 goods[0] 填充到 goods[11]:

strcpy(goods[11].goods_descrip, "Dish");
strcpy(goods[11].goods_code, "00713");
goods[11].price = 25.00;

【讨论】:

    【解决方案2】:

    你犯了几个错误。让我指出它们:- Keine Lust 指出的第一个:https://stackoverflow.com/a/40690102/3959321,您通过迭代到 12(包括)来访问数组边界之外的内存。如果您声明了一个包含 12 个元素的数组,则索引的范围是 0 到 11,而不是 0 到 12

    for (i = 0; i <= 12; ++i){  //wrong iterations (< 12 should be here)
        if (strcmp(tempCode, goods[i].goods_code) == 0) {
            strcpy(receiptNM, goods[i].goods_descrip);
            strcpy(receiptCD, goods[i].goods_code);
            receiptPC = goods[i].price;
            ttlcost += goods[i].price;
        }
        else {
            printf("This item code does not exist! Try again!\n");
        }
        printf("Please enter the item code. Type F to finish");
        scanf("%s", &tempCode);
    }
    

    您的程序肯定会打印 12 次“此项目代码不存在!...”,因为 else 部分与 if 相关联并嵌套在 for 循环中。 因此,每次循环 12 次迭代都没有找到 item 时会调用它。

    正确的程序是:-

    ----   //Rest above is same
    unsigned int i;
    printf("Please enter the item code. Type F to finish");
    scanf("%s", tempCode);
    
    while ( strcmp(tempCode, stop) ) {
        for (i = 0; i < 12; ++i){
            if (strcmp(tempCode, goods[i].goods_code) == 0){
                strcpy(receiptNM, goods[i].goods_descrip);
                strcpy(receiptCD, goods[i].goods_code);
                receiptPC = goods[i].price;
                ttlcost += goods[i].price;
                break;
            }
        }
        if (i==12)   //The loop iteration is complete, and i becomes 12 only when the for above hasn't been breaked (same as item found)
            printf("This item code does not exist! Try again!\n");
        printf("Please enter the item code. Type F to finish");
        memset(tempCode,'\0',sizeof(tempCode));
        scanf("%s", tempCode);
    }
    

    你在最后的收据部分也犯了一个错误:-

    printf("%10s%20s%10s", "Item", "Code", "Price");
    printf("%10s%20s%10.2f\n", receiptNM, receiptCD, receiptPC); //receiptNM, receiptCD and receiptPC are only single character arrays. 
    

    与您的预期不同,它们只会存储一个字符串。为了存储所有这些,您制作了一个结构数组(包含商品代码、商品名称和价格)。按照 GumBoy 的回答:- https://stackoverflow.com/a/40690211/3959321

    【讨论】:

      【解决方案3】:

      查看您的输出图像。您将需要一个 for 循环来打印出这些值。在您当前的程序中,每次满足 if 语句中的条件时,receiptCD、reciptNM 和 recieptPC 的值都会被替换。我认为您需要为收据添加另一个 typedef 结构。

      我解决了一些问题,但你几乎就在那里。最后是文本的理由。

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      int main()
      {
      typedef struct goods
      {
      char goods_code[6];
      char goods_descrip[20];
      float price;
      }goodtype;
      
      goodtype goods[13];
      strcpy(goods[0].goods_descrip, "Chicken");
      strcpy(goods[0].goods_code, "00310");
      goods[0].price = 35.00;
      
      strcpy(goods[1].goods_descrip, "Pork");
      strcpy(goods[1].goods_code, "00311");
      goods[1].price = 20.50;
      
      strcpy(goods[2].goods_descrip, "Beef");
      strcpy(goods[2].goods_code, "00322");
      goods[2].price = 45.00;
      
      strcpy(goods[3].goods_descrip, "Fish");
      strcpy(goods[3].goods_code, "00323");
      goods[3].price = 40.00;
      
      strcpy(goods[4].goods_descrip, "Walmart T Shirt");
      strcpy(goods[4].goods_code, "00510");
      goods[4].price = 75.00;
      
      strcpy(goods[5].goods_descrip, "Walmart Trousers");
      strcpy(goods[5].goods_code, "00511");
      goods[5].price = 120.00;
      
      strcpy(goods[6].goods_descrip, "Walmart Coat");
      strcpy(goods[6].goods_code, "00512");
      goods[6].price = 100.00;
      
      strcpy(goods[7].goods_descrip, "Walmart Jumper");
      strcpy(goods[7].goods_code, "00513");
      goods[7].price = 85.00;
      
      strcpy(goods[8].goods_descrip, "Mug");
      strcpy(goods[8].goods_code, "00710");
      goods[8].price = 15.50;
      
      strcpy(goods[9].goods_descrip, "Fry Pan");
      strcpy(goods[9].goods_code, "00711");
      goods[9].price = 200.00;
      
      strcpy(goods[10].goods_descrip, "Bowl");
      strcpy(goods[10].goods_code, "00712");
      goods[10].price = 25.00;
      
      strcpy(goods[11].goods_descrip, "Dish");
      strcpy(goods[11].goods_code, "00713");
      goods[11].price = 25.00;
      
      char tempCode[6];
      typedef struct receipt
      {
      char receiptNM[20], receiptCD[6];
      float receiptPC;
      }receipttype;
      receipttype receipt[13];
      char stop[2] = {"F"};
      float ttlcost = 0;
      unsigned int i;
      unsigned int count = 0;
      
      
      
      while ( strcmp(tempCode, stop) ){
      printf("Please enter the item code. Type F to finish: ");
      scanf("%s", tempCode);
      for (i = 0; i <= 12; ++i){
          if (strcmp(tempCode, goods[i].goods_code) == 0){
              strcpy(receipt[count].receiptNM, goods[i].goods_descrip);
              strcpy(receipt[count].receiptCD, goods[i].goods_code);
              receipt[count].receiptPC = goods[i].price;
              ttlcost += goods[i].price;
              count++;
          }
      
      }
      
      }
      printf("_____________________________________\n\n");
      printf("      THANK YOU FOR VISITING US!     \n");
      printf("_____________________________________\n");
      printf("         Here is your receipt:       \n\n");
      printf("%10s%20s%10s", "Item", "Code", "Price\n");
      for (int j= 0; j < count; ++j){
      printf("%10s%20s%10.2f\n", receipt[j].receiptNM, receipt[j].receiptCD, receipt[j].receiptPC);
      }
      printf("\n_____________________________________\n");
      printf("          TOTAL COST:%.2f            \n", ttlcost);
      }
      

      【讨论】:

        【解决方案4】:

        由于没有其他人提到它,这里有一个更好的方法来填充结构数组。

        typedef struct
        {
            char  *code;
            char  *description;
            float price;
        }goodtype;
        
        static goodtype goods[] =
        {
            { "00310", "Chicken" ,  35.00 },
            { "00311", "Pork"    ,  20.50 },
            { "00322", "Beef"    ,  45.00 },
            { "00323", "Fish"    ,  40.00 },
            { "00510", "T Shirt" ,  75.00 },
            { "00511", "Trousers", 120.00 },
            { "00512", "Coat"    , 100.00 },
            { "00513", "Jumper"  ,  85.00 },
            { "00710", "Mug"     ,  15.50 },
            { "00711", "Fry Pan" , 200.00 },
            { "00712", "Bowl"    ,  25.00 },
            { "00713", "Dish"    ,  25.00 }
        };
        static int goodscount = sizeof(goods) / sizeof(goods[0]);
        
        int main( void )
        {
            for ( int i = 0; i < goodscount; i++ )
                printf( "%3d %s %s\n", i, goods[i].code, goods[i].description );
            printf( "Number of items: %d\n", goodscount );
        }
        

        这样做有几个好处:

        • 输入更少,减少人为错误的机会
        • 节省一点内存,因为您无需猜测code 和description 数组需要多大。
        • 避免缓冲区溢出的可能性(例如,如果您猜错了字符串的长度)。
        • 节省一点时间,因为您不需要做所有这些strcpys。
        • 自动计算数组中的条目数,因此您不会弄错。

        【讨论】:

        • 我调整了我的程序,现在看起来更整洁了:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-04
        • 2011-10-11
        • 1970-01-01
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多