Windows下VScode+GCC开发环境搭建

仓促报名参加神机妙算2021算法设计大赛,大赛要求使用gcc9.3.0编译,为了便于队友开发,建立windows下的vscode+gcc9.3的开发环境。过程如下。

1. 安装mingw环境

该部分文档见:

(如何安装MinGW - 简书 (jianshu.com))

mingw为在windows下模拟GUN/Linux工具链的一套软件,其中包括g++和gcc编译器。

解压文件x86_64-8.1.0-release-posix-seh-rt_v6-rev0.zip或者x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z

从解压 文件夹中复制文件夹mingw64到另外一个文件夹,例如到D:\Program Files\下(其他路径也可以)

img

在bin文件夹下可以看到gcc.exeg++.exe

img

将g++和gcc所在bin文件夹路径添加到系统环境变量:

img

img

img

设置环境变量,注意在系统变量中添加.

img

编辑环境变量

img

重启电脑!

实验是否安装成功
输入命令 gcc,得到如图结果说明已经成功配置环境变量

img

2 VSCode配置gcc/g++编译器

该部分文档参考

VSCode在windows下使用MinGW-w64的gcc/g++编写调试程序_itas109的专栏-CSDN博客

2.1 安装VSCode

省略

2.2 安装VScode插件

VScode支持很多插件,打开VScode后,单击左边插件按钮:

可以在搜索栏搜索c++,然后安装截图中的插件,包括C/C++,CMake,CMake Tools等。

搜索Chinese 可以搜到Chinese(Simplified) Language Pack插件,为中文简体语言包,可以把vscode汉化。

或者安装C/C++ Extension Pack,该扩展插件会把C和C++常用插件都给安装了。还有一个Tabnine的自动补全插件,很管用。

2.3 配置插件

点击菜单File->Open Folder打开工作目录,例如我建立了D:\Docs\Code\dev_cpp路径,然后把case1文件夹里的文件复制过去,然后,按Ctrl+Shift+P或者菜单:View->Command Palette打开命令面板。

点击C/C++:Edit Configurations(JSON),打开C/C++配置文件,c_cpp_properties.json.

修改如下:

注意在修改的时候,由于windows下路径分隔符为“\”,为了避免转义,需要用"\\"替代。

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "windowsSdkVersion": "10.0.17763.0",
            "compilerPath": "D:\\Program Files\\mingw64\\bin\\g++.exe",
            "cStandard": "c11",
            "cppStandard": "c++11",
            "intelliSenseMode": "clang-x64"
        }
    ],
    "version": 4
}

注意将compilerPath修改为你安装gcc/g++所在的g++.exe的路径,按照比赛要求,将"cStandard""cppStandard"修改成为c11c++11,智能提示模式"intelliSenseMode"修改成clang-x64

修改task配置,按ctrl+shift+p打开命令窗口,输入task,选择Tasks:Configure Task,则会打开task.json的配置文件。

自动生成的task.json后,修改配置如下:

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "cppbuild",
			"label": "g++", // 任务名称
			"command": "g++.exe",
			"args": [
				"-g",
				"${file}",
				"-o",
				"${workspaceFolder}\\${fileBasenameNoExtension}.exe"
			],
			"options": {
				"cwd": "C:\\Windows\\System32" //该处修改成cmd.exe命令所在处,一般windows为C:\Windows\System32,该处和帖子里不一样
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": {
				"kind": "build",
				"isDefault": true                 //为 True 时,用户可以通过 Ctrl+Shift+B 直接运行编译任务 
			},
			"detail": "编译器: \"D:\\Program Files\\mingw64\\bin\\g++.exe\""
		}
	]
}

通过调试,打开配置文件,launch.json

修改为如下代码:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) 启动",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
      "args": [ //注意这次比赛的exe输入参数为input.txt和output.txt作为输入,所以在这要加调试参数,要不然会有空指针错误(示例代码没考虑这种情况)
        "input.txt",
        "output.txt"
      ],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "D:\\Program Files\\mingw64\\bin\\gdb.exe",
      "preLaunchTask": "g++",
      "setupCommands": [
        {
          "description": "为 gdb 启用整齐打印",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ]
    },
    {//该任务无所谓,不执行。
      "name": "C/C++ Runner: Debug Session",
      "type": "cppdbg",
      "request": "launch",
      "args": [],
      "stopAtEntry": false,
      "cwd": "d:\\Docs\\Code\\dev_cpp",
      "environment": [],
      "program": "d:\\Docs\\Code\\dev_cpp\\build\\Debug\\outDebug",
      "internalConsoleOptions": "openOnSessionStart",
      "MIMode": "gdb",
      "miDebuggerPath": "D:\\Program Files\\mingw64\\bin\\gdb.exe",
      "externalConsole": false
    }
  ]
}

3 编译和调试

为了体现调试和读参数效果,我们修改case1.cpp代码如下:

// Copyright (c) 2021 xxx.Co.Ltd. All rights reserved.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
// 将文件读取到string集合中
void ReadFileByLine(const std::string &filename,
                    std::vector<std::string> &lines);

// 将string集合写入文件
void WriteFileFromVector(const std::string &filename,
                         std::vector<std::string> &lines);

// 字符串Trim函数
void TrimString(std::string &s);

// 你需要实现代码实现的函数
void YourFunction(const std::vector<std::string> &input_lines,
                  std::vector<std::string> &output_lines);

int main(int argc, char* argv[]) {
    // 此为原始数据文件路径,提交时请勿修改,擅自修改会导致运行找不到文件而报错
    const std::string k_input_filename {argv[1]};

    // 此为结果文件路径,提交时请勿修改,擅自修改会导致评测系统无法获取结果文件
    const std::string k_output_filename {argv[2]};

    // 定义两个字符串迭代器,分别存储输入和输出内容
    std::vector<std::string> input_lines, output_lines;

    // 将输入文件读取到input_lines迭代器中
    ReadFileByLine(k_input_filename, input_lines);

    // 你需要实现代码实现的函数
    YourFunction(input_lines, output_lines);

    // 将output_lines迭代器写到输出文件中
    WriteFileFromVector(k_output_filename, output_lines);

    return 0;
}

// 你需要实现代码实现的函数
void YourFunction(const std::vector<std::string> &input_lines,
                  std::vector<std::string> &output_lines) {
    // 请实现你的代码,将结果按行写到output_lines中
    cout <<"This is my function" << endl;//SPY加入
}


// 将文件读取到string集合中
void ReadFileByLine(const std::string &filename,
                    std::vector<std::string> &lines) {
    std::ifstream infile(filename);
    cout<<filename<<endl;//显示输入文件名字
    if ( !infile.good() ) {
        std::cout << "Error opening input file" << std::endl;
        exit(-1);
    }

    std::string line;

    while ( getline(infile, line) ) {
        TrimString(line);
        if (!line.empty()) lines.push_back(line);
    }

    infile.close();
    infile.clear();
}

// 将string集合写入文件
void WriteFileFromVector(const std::string &filename,
                         std::vector<std::string> &lines) {
    std::ofstream outfile(filename, std::ios::out);

    if ( !outfile.good() ) {
        std::cout << "Error opening output file" << std::endl;
        exit(-1);
    }

    for (const auto& line : lines)
        outfile << line << std::endl;

    outfile.close();
    outfile.clear();
}


// 字符串Trim函数
void TrimString(std::string &s) {
    if (s.empty()) return;

    while (s[0] == ' ' || s[0] == '\t' || s[0] == '\r' || s[0] == '\n') {
        s.erase(0, 1);
    }

    while (s[s.length()] == ' ' || s[s.length()] == '\t'
    || s[s.length()] == '\r' || s[s.length()] == '\n') {
        s.erase(s.length(), 1);
    }
}

然后在读取输入文件的函数出加入断点(快捷键F9):

然后启动调试(按快捷键F5):

则光标会停到该行,


然后在底部的调试控制台我们可以看到,停在了断点处,而且能把filename="input.txt"显示出来,证明参数传递正确。

按F10单步执行,可以看出来光标到了下一行:

点到终端选项卡:

可以看出来把传进去的参数文件名读取正确:

再按F5继续往下执行,则执行完之后,终端打印出来"This is my function",和代码里49行一致,所以证明编译和调试功能都正确。至此,编译和调试环境建立完成。可以当一个IDE用了。

posted @ 2021-07-04 23:34  SpyCoder  阅读(45)  评论(0)    收藏  举报