最近几天看了一点黑马程序员的视频(没什么基础),试着跟着写了一下实现通讯录管理的代码(暂时只完成了一部分功能),想要在 Linux 系统下实现类似 Windows 里 `system("pause")` 的功能,比如在通讯录中写完一个联系人的信息或者显示一个联系人的信息的时候能够 Pause 一下。。代码如下

```
#include <iostream>
using namespace std;

#include <string>
#include <limits> // 定义 pause 函数以及 getValidInput 函数中使用

#define MAX 1000 // 通讯录最大人数

void showMenu ();
void pause ();

int getValidInput ();

// 联系人结构体
struct Person {
    string m_Name;
    int m_Gender;
    int m_Age;
    long m_Phone;
    string m_Address;
};

// 通讯录结构体
struct Addressbooks {
    struct Person personArray[MAX];
    int m_Size; // 通讯录中人员个数
};

void addPerson (Addressbooks *abs);
void showPerson (Addressbooks *abs);

int main () {
    struct Addressbooks abs;
    abs.m_Size = 0;

    while (true) {
        showMenu(); // 菜单调用
        // cin >> select;

        // 检查输入是否有效
        // if (cin.fail()) {
        //     cin.clear(); // 清除错误状态
        //     cin.ignore(numeric_limits<streamsize>::max(),'\n'); // 清空缓冲区
        //     cout << "请输入有效的数字!" << endl;
        //     continue; // 重新进入循环
        // }
        int select = getValidInput ();

        switch (select) {
            case 1: // 添加联系人
                addPerson(&abs); // 利用地址传递,可以修饰实参
                break;
            case 2:
                showPerson(&abs);
                break;
            case 3:
                break;
            case 4:
                break;
            case 5:
                break;
            case 6:
                break;
            case 0:
                cout << "欢迎下次使用" << endl;
                // pause();
                return 0;
                // break;
            default:
                cout << "请输入数字 1-6 或 0" << endl;
                break;
        }
    }

    return 0;
}

void showMenu () {
    cout << "1 、添加联系人" << endl;
    cout << "2 、显示联系人" << endl;
    cout << "3 、删除联系人" << endl;
    cout << "4 、查找联系人" << endl;
    cout << "5 、修改联系人" << endl;
    cout << "6 、清空联系人" << endl;
    cout << "0 、退出通讯录" << endl;
}

// 实现类似 Windows 系统上的 system("pause") 功能
void pause () {
    cin.clear();
    // if (cin.eof()) {
        cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略输入流中的内容直到换行符,但因为输入内容已经被清空,这里程序会等待输入一个回车(换行符)
    // }
    cout << "请按回车键继续" << endl;
    cin.get();
}

// 检测输入数据是否为整数,是则返回该输入
int getValidInput () {
    int input;
    while (true) {
        cin >> input;
        if (cin.fail()) {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "请输入有效的数字!" << endl;
        }
        else {
            if (cin.eof()) {
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
            }
            return input;
        }
    }
}

// 添加联系人
void addPerson (Addressbooks *abs) {
    // 判断通讯录是否已满
    if (abs->m_Size == MAX) {
        cout << "通讯录已满,无法添加联系人!" << endl;
        return;
    }
    else {
        string name;
        cout << "请输入联系人姓名:" << endl;
        cin >> name;
        abs->personArray[abs->m_Size].m_Name = name;

        cout << "请输入联系人性别:" << endl;
        cout << "输入数字 1 为男性" << endl;
        cout << "输入数字 2 为女性" << endl;

        while (true) {
            // cin >> gender;

            // if (cin.fail()) {
            //     cin.clear();
            //     cin.ignore(numeric_limits<streamsize>::max(), '\n');
            //     cout << "请输入有效的数字!" << endl;
            //     continue;
            // }

            int gender = getValidInput ();

            if (gender == 1 || gender == 2) {
                abs->personArray[abs->m_Size].m_Gender = gender;
                break;
            }

            cout << "输入有误,请重新输入" << endl;
        }

        cout << "请输入联系人年龄:" << endl;
        int age = getValidInput ();
        abs->personArray[abs->m_Size].m_Age = age;

        cout << "请输入联系人电话号码:" << endl;
        long phone;
        cin >> phone;
        abs->personArray[abs->m_Size].m_Phone = phone;

        cout << "请输入联系人家庭住址:" << endl;
        string address;
        cin >> address;
        abs->personArray[abs->m_Size].m_Address = address;

        cout << "已成功添加联系人 " << abs->personArray[abs->m_Size].m_Name << endl;
        abs->m_Size++;

        pause();
        system("clear"); // 对于 Windows 系统,应该使用 system("cls")
    }
}

void showPerson (Addressbooks *abs) {
    if (abs->m_Size == 0) {
        cout << "当前记录为空" << endl;
    }
    else {
        for (int i=0;i<abs->m_Size;i++) {
            cout << "姓名:" << abs->personArray.m_Name << endl;
            cout << "性别:" << abs->personArray.m_Gender << endl;
            cout << "年龄:" << abs->personArray.m_Age << endl;
            cout << "电话:" << abs->personArray.m_Phone << endl;
            cout << "地址:" << abs->personArray.m_Address << endl;
        }
    }
    pause();
    system("clear");
}
```

然后我发现在我定义的函数 `getValidInput` 里面加入一个 `cin.eof()` 的判断就基本实现了我想要的效果,但其实我不太理解原因是什么,特别是如果我把 `getValidInput` 函数的这个判断给注释掉的话,那么在我输入 "2" 使用 "显示联系人" 这个功能时,需要再输入一个回车才会显示 "请按回车键继续" 的字符;而如果我仍然注释 `getValidInput` 中的这个判断,但取消 `pause` 函数定义中关于 `cin.eof()` 的注释(见上面的代码),那么在我输入 "1" 使用 "添加联系人" 的功能的时候,在我输入完联系人信息之后,`pause()` 似乎不会起作用,`system("clear")` 会直接清屏。。
举报· 127 次点击
登录 注册 站外分享
8 条回复  
sagaxu 初学 2024-10-18 21:39:24
system("read -n 1")
wshcdr 小成 2024-10-18 21:38:58
#include <iostream>

int main() {
    std::cout << "Press any key to continue..." << std::endl;
    std::cin.get();  // 等待用户按下一个键
    std::cout << "Continuing..." << std::endl;
    return 0;
}
yanqiyu 小成 2024-10-18 21:38:07
general: cin.eof 除非我按 Ctrl+D ,或者 pipe 进来个文件,否则始终是 false ,所以有那个判断大概就是等价于删掉它包起来的代码。(并且一般交互式程序遇到 end of cin 大概就该结束了)

> 特别是如果我把 getValidInput 函数的这个判断给注释掉的话,那么在我输入 "2" 使用 "显示联系人" 这个功能时,需要再输入一个回车才会显示 "请按回车键继续" 的字符

cin.ignore(numeric_limits<streamsize>::max(), '\n'); 会一直等输入(堵塞)直到遇到回车,要是缓冲区里面没有回车的话。

> 而如果我仍然注释 getValidInput 中的这个判断,但取消 pause 函数定义中关于 cin.eof() 的注释(见上面的代码),那么在我输入 "1" 使用 "添加联系人" 的功能的时候,在我输入完联系人信息之后,pause() 似乎不会起作用,system("clear") 会直接清屏。。

那大概是缓冲区里面 somehow 留了一个\n...要是没有前面的 ignore 把它耗掉它就把那个 std::cin.get() pass 掉了
ysc3839 小成 2024-10-18 21:27:03
好像要关掉行缓冲,然后就能接收到单个字符输入了,收到之后继续运行即可。
cnbatch 初学 2024-10-18 21:24:04
system()本质是运行命令行的命令,所以 system("pause")意思就是在 Windows 调用 pause 命令

如果是想通用一点,那就把 system("pause")替换成
printf("Press enter to continue");
int c = getchar();
返回顶部