You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

邮局/银行柜台管理程序代码求专业建议与优化指导

Post Office Counter Management Program Improvements

Hey Tyler, thanks for sharing your code! Let's walk through how we can align it better with the requirements you listed, plus fix some key issues in the current implementation.

First, Let's Break Down the Gaps Between Your Code and the Requirements

Your current code has some good foundations, but it doesn't fully meet the core flow the requirements outline:

  • Queue Management: The requirements call for separate waiting queues for service A and B, with counters calling the next user from a queue only when they're free. Right now, you're assigning a random counter immediately when a user takes a number—this skips the waiting queue logic entirely.
  • Counter Call Trigger: The code doesn't simulate the "柜员按下按钮呼叫" (teller presses button to call next user) action. Instead, it shows a counter assignment right after take-a-number, which isn't how real counter systems work.
  • Exit Logic: The current exit flow is confusing (asking for "Exit" after pressing 0) and doesn't tie into the counter operation flow.
  • Undefined Behavior: Using fflush(stdin) is not standard C and can cause unexpected behavior across different compilers.
  • Random Number Issue: Calling srand(time(NULL)) inside the loop means if you run through the loop quickly (within the same second), you'll get the same "random" counter number every time.

Key Improvements to Implement

Let's fix these issues and build a version that matches the requirements step by step:

1. Add Proper Queue Structures for Service A and B

We'll use simple array-based queues to track waiting users for each service. Each queue will track the next number to assign and the list of waiting users.

2. Track Counter Statuses

We'll have an array to track if each of the 3 counters is free or busy. When a counter is free, a teller can trigger a call to the next user in either A or B queue.

3. Fix Input Handling

Replace fflush(stdin) with a helper function to clear leftover input characters, which is standard-compliant.

4. Separate Take-a-Number and Counter Call Flows

Create a main menu that lets users either take a number or trigger a counter call (simulating the teller's button press).

Revised Code Implementation

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

#define MAX_QUEUE_SIZE 100
#define NUM_COUNTERS 3

// Helper function to clear input buffer
void clear_input_buffer() {
    while (getchar() != '\n');
}

typedef struct {
    int next_number;
    int queue[MAX_QUEUE_SIZE];
    int front;
    int rear;
} ServiceQueue;

// Initialize a service queue
void init_queue(ServiceQueue *q) {
    q->next_number = 1;
    q->front = 0;
    q->rear = -1;
}

// Add a user to the queue (issue a ticket)
bool enqueue(ServiceQueue *q) {
    if (q->rear >= MAX_QUEUE_SIZE - 1) {
        printf("Sorry, this service queue is full. Please try again later.\n");
        return false;
    }
    q->rear++;
    q->queue[q->rear] = q->next_number;
    q->next_number++;
    return true;
}

// Get the next user from the queue (call a user)
int dequeue(ServiceQueue *q) {
    if (q->front > q->rear) {
        printf("No users waiting for this service.\n");
        return -1;
    }
    int user_number = q->queue[q->front];
    q->front++;
    return user_number;
}

int main() {
    ServiceQueue queueA, queueB;
    init_queue(&queueA);
    init_queue(&queueB);
    
    // 0 = free, 1 = busy
    int counter_status[NUM_COUNTERS] = {0, 0, 0};
    
    srand(time(NULL)); // Initialize random seed once at start
    
    int choice;
    do {
        printf("\n=== Post Office Counter Management System ===\n");
        printf("1. Take a service ticket (A/B)\n");
        printf("2. Teller: Call next user (counter 1/2/3)\n");
        printf("3. Exit\n");
        printf("Enter your choice: ");
        
        // Handle invalid input
        while (scanf("%d", &choice) != 1) {
            clear_input_buffer();
            printf("Invalid input. Please enter a number: ");
        }
        clear_input_buffer();
        
        switch (choice) {
            case 1: {
                char service;
                printf("Select service type (A/B): ");
                scanf(" %c", &service);
                clear_input_buffer();
                
                if (service == 'A' || service == 'a') {
                    if (enqueue(&queueA)) {
                        printf("=== Ticket Issued ===\n");
                        printf("Service: A | Number: %d\n", queueA.next_number - 1);
                    }
                } else if (service == 'B' || service == 'b') {
                    if (enqueue(&queueB)) {
                        printf("=== Ticket Issued ===\n");
                        printf("Service: B | Number: %d\n", queueB.next_number - 1);
                    }
                } else {
                    printf("Invalid service type. Please choose A or B.\n");
                }
                break;
            }
            case 2: {
                int counter_num;
                printf("Enter counter number (1-%d): ", NUM_COUNTERS);
                while (scanf("%d", &counter_num) != 1 || counter_num < 1 || counter_num > NUM_COUNTERS) {
                    clear_input_buffer();
                    printf("Invalid counter number. Enter 1-%d: ", NUM_COUNTERS);
                }
                clear_input_buffer();
                counter_num--; // Convert to 0-based index
                
                if (counter_status[counter_num] == 1) {
                    printf("Counter %d is currently busy. Please wait until it's free.\n", counter_num + 1);
                    break;
                }
                
                char service_call;
                printf("Call user from service (A/B): ");
                scanf(" %c", &service_call);
                clear_input_buffer();
                
                int user_num = -1;
                if (service_call == 'A' || service_call == 'a') {
                    user_num = dequeue(&queueA);
                } else if (service_call == 'B' || service_call == 'b') {
                    user_num = dequeue(&queueB);
                } else {
                    printf("Invalid service type. Please choose A or B.\n");
                    break;
                }
                
                if (user_num != -1) {
                    counter_status[counter_num] = 1; // Mark counter as busy
                    // Display on waiting area screen
                    printf("\n=== WAITING AREA DISPLAY ===\n");
                    printf("SP %d SRV %c N %d to Counter %d\n", 
                           (service_call == 'A' || service_call == 'a') ? 1 : 2, 
                           service_call, user_num, counter_num + 1);
                    
                    // Simulate service completion (optional: let user mark counter as free)
                    printf("\nPress any key when counter %d has finished servicing the user...\n", counter_num + 1);
                    getchar();
                    counter_status[counter_num] = 0; // Mark counter as free
                }
                break;
            }
            case 3:
                printf("Exiting system. Thank you!\n");
                break;
            default:
                printf("Invalid choice. Please enter 1, 2, or 3.\n");
        }
    } while (choice != 3);
    
    return 0;
}

Key Changes Explained

  • Queue System: We now have proper enqueue (issue ticket) and dequeue (call user) functions for each service, which matches the requirement of waiting queues.
  • Counter Status Tracking: The counter_status array keeps track of whether a counter is free or busy, so we don't call users to busy counters.
  • Input Handling: The clear_input_buffer function safely clears leftover input without using fflush(stdin), avoiding undefined behavior.
  • Separate Flows: The main menu lets users either take a ticket (simulating the entry device) or trigger a counter call (simulating the teller's button press), which aligns perfectly with requirements 3 and 4.
  • Display Logic: When a user is called, the waiting area display shows the exact format required: SP [service indicator] SRV [A/B] N [number] to Counter [X] (adjust the display string wording if you need to match your example exactly).

Additional Suggestions

If you want to make the system more realistic, you could add:

  • A timeout for counter service (instead of waiting for user input to mark it free).
  • Statistics tracking (total users served per service, average wait time).
  • Priority handling (if some services need priority over others).

内容的提问来源于stack exchange,提问作者Tyler Lambert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 21:17:42