记录第三周的C++作业


作业要求

"""
一、使用命令CPUInfo.exe -c 读取本机CPU的信息,并存储到INI格式的文本中:
示例如下:
[CPU]
Manufacturer=AuthenticAMD
BrandID=AMD Athlon Gold 3150U with Radeon Graphics
CPUID=0F81
Cores=2
HyperThread=True
MainClock=2396MHZ
L1CacheSize=192KB
L2CacheSize=1024KB
L3CacheSize=4096KB
二、使用命令CPUInfo.exe -r 读取INI文本中CPU的信息,并打印到控制台上:
"""

包含的头文件

#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <codecvt>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <io.h>

全局变量与函数

using namespace std;
void getcmd_info(FILE* fp);
void clean_temp();
void get_temp();
void write_ini();
void read_ini();
int file_exists(const char* filename);
int write_info(const std::string& file_string, const std::string str);
struct cpu_info
{
    string value;
};
cpu_info name[9];
cpu_info result[9];

main函数

int main(int nArgc, char* argv[])
{
    //判断参数个数与内容
    if (nArgc == 2 && !_stricmp(argv[1], "-c"))
    {
        //首先重置缓存文件
        clean_temp();
        //从缓存文件中读取信息并存入结构体变量
        get_temp();
        //清洗所需信息,并按格式保存进ini文件
        write_ini();
        //删除缓存文件
        system("DEL temp.txt");
        cout << "OK!";
    }
    else if (nArgc == 2 && !_stricmp(argv[1], "-r"))
    {
        //判断ini文件是否已经存在,如果不存在则进行生成
        if (!file_exists("result.ini"))
        {
            printf("Configuration File Does Not Exist And is Being Written...\n");
            clean_temp();
            get_temp();
            write_ini();
            system("DEL temp.txt");
            cout << "OK! Please Try Again!";
        }
        //如果存在则进行读取
        else
        {
            read_ini();
        }
    }
    //没有额外参数时则什么都不做
    else if (nArgc == 1)
    {
        return 1;
    }
    else
    {
        cout << "Parameter Error!";
    }
}

几个函数

//判断文件是否存在,不存在则返回0
int file_exists(const char* filename)
{
    //文件不存在时调用_access函数返回的值是1
    return (_access(filename, 0) == 0);
}
//获取cmd命令行中的输出信息,并写入缓存文件里
void getcmd_info(FILE* fp)
{
    //以写状态打开文件
    FILE* fp2 = fopen("temp.txt", "a");
    char buf[100];

    if (!fp)
    {
        return;
    }
    //每次写一行
    while (memset(buf, 0, sizeof(buf)), fgets(buf, sizeof(buf) - 1, fp) != 0)
    {
        fprintf(fp2, "%s", buf);
    }
    fclose(fp2);
}
//将字符串类型变量写入指定文件
int write_info(const std::string& file_string, const std::string str)
{
    std::ofstream   OsWrite(file_string, std::ofstream::app);
    OsWrite << str;
    OsWrite << std::endl;
    OsWrite.close();
    return 0;
}
//从temp中读取信息,按规则进行清洗,并转为string字符串,再将信息存入结构体变量
void get_temp()
{
    int n, j = 0;
    char str[256];
    FILE* fp2 = fopen("temp.txt", "r");
    while (j <= 8)
    {
        for (int i = 1; i <= 3; i++)
        {
            fgets(str, 100, fp2);
            if (str[strlen(str) - 1] == '\n')
            {
                str[strlen(str) - 1] = '\0';
                switch (i)
                {
                case(1):
                {

                    n = strlen(str);
                    string s;
                    for (int m = 0; m < n - 1; m++)
                    {
                        if (str[m] != ' ')
                        {
                            s += str[m];
                        }
                        else
                        {
                            break;
                        }
                    }
                    name[j].value = s;
                    break;
                };
                case(2):
                {
                    n = strlen(str);
                    string s;
                    for (int m = 0; m < n - 1; m++)
                    {
                        if (str[m] != ' ')
                        {
                            s += str[m];
                        }
                        else if (str[m + 1] != ' ')
                        {
                            s += str[m];
                        }
                        else { break; }
                    }
                    result[j].value = s;
                    break;
                };
                case(3):
                {
                    break;
                };
                };
            }
        }
        j++;
    }
    fclose(fp2);
}
//初始化缓存文件中的信息
void clean_temp()
{
    int i = 0;
    FILE* fp = fopen("temp.txt", "w");
    fclose(fp);
    char result_info[256];
    //要读取的内容
    char cmd[9][256] = { "Manufacturer","Name","ProcessorId","NumberOfCores",
                        "NumberOfLogicalProcessors","CurrentClockSpeed","DataWidth",
                        "L2CacheSize","L3CacheSize" };
    FILE* fp1 = NULL;
    while (i < 9)
    {
        //将预处理命令行信息写入字符数组
        sprintf_s(result_info, "wmic CPU get %s", cmd[i]);
        fp1 = NULL;
        //调用_popen函数抓取输出信息
        fp1 = _popen(result_info, "r");
        if (!fp1) {
            perror("popen");
            exit(EXIT_FAILURE);
        }
        //将信息写入缓存文件
        getcmd_info(fp1);
        _pclose(fp1);
        i++;
    }
}
//将清洗完毕的数据按所需规则存入ini文件,并添加单位
void write_ini()
{
    int cores = 0;
    FILE* fp3 = fopen("result.ini", "wt");
    fclose(fp3);
    write_info("result.ini", string("[CPU]"));
    for (int i = 0; i < 9; i++)
    {
        string s;
        if (name[i].value == "CurrentClockSpeed")
        {
            s = name[i].value + " = " + result[i].value + "MHZ";
        }
        else if (name[i].value == "L2CacheSize" | name[i].value == "L3CacheSize")
        {
            s = name[i].value + " = " + result[i].value + "KB";
        }
        else if (name[i].value == "NumberOfCores")
        {
            string res = result[i].value;
            stringstream ss;
            stringstream sp;
            ss << res;
            ss >> cores;
            s = name[i].value + " = " + result[i].value;
        }
        else if (name[i].value == "DataWidth")
        {
            //这里是字符串与数值的互转
            int z;
            name[i].value = "L1CacheSize";
            string res = result[i].value;
            stringstream ss;
            stringstream sp;
            ss << res;
            ss >> z;
            z *= cores;
            sp << z;
            sp >> res;
            result[i].value = res;
            s = name[i].value + " = " + result[i].value + "KB";
        }
        else
        {
            s = name[i].value + " = " + result[i].value;
        }
        //调用写字符串函数,传递的两个参数分别是文件名和预写入信息
        write_info("result.ini", s);
    }
}
//循环读取ini文件中的每一行信息
void read_ini()
{
    char t[256]; int i = 1, n;
    FILE* fp = fopen("result.ini", "r");
    while (i)
    {
        fgets(t, 256, fp);
        n = strlen(t);
        if (t[n - 1] == '\n')
        {
            t[n - 1] = '\0';
            printf("%s\n", t);
        }
        else
        {
            i = 0;
        }
    }
}

总结

写的比较繁琐,而且一级缓存并没有正确的读出来,需要更明确的方法。