Introduction

Easylogging++ C'est pour C++ Une bibliothèque de journaux efficace à un seul en - tête pour l'application.C'est très puissant,Très extensible et configurable à la demande de l'utilisateur.githubLiens:https://github.com/amrayn/easyloggingpp.

Easylogging++ Inv9.89L'édition n'a qu'un seul fichier d'en - tête,Puis changez - le en fichier d'en - tête、Un fichier source,La dernière version estv9.97(La version utilisée dans cet article).

Utiliser

Utiliser Easylogging++Il suffit de trois étapes simples:

  • Télécharger la dernière version
  • Oui.easylogging++.hEteasylogging++.ccInclus dans le projet
  • Initialisation avec une seule macro
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
int main(int argc, char* argv[]) {
LOG(INFO) << "My first info log using default logger";
return 0;
}

Extension

Easylogging++Le journal par défaut est écrit dans un fichier,Et il n'y a pas de fonction pour créer un nouveau journal par date,J'ai besoin de m'agrandir.Les fonctions étendues sont les suivantes:

  • Les fichiers journaux sont placés sur une base annuelle、Dans le dossier généré par le mois,Un fichier journal distinct par niveau de journal,Par exemple:“Log\2021\202108\20210818_INFO.log”
  • Générer de nouveaux fichiers journaux tous les jours,C'est - à - dire que les fichiers journaux défilent par date
  • Supprimer automatiquement en fonction de la dernière modification du fichier journalnLe fichier journal de l'autre jour,Prise en charge uniquementWindowsSystème

Je vais essayer d'utiliser la Bibliothèque standard etEasylogging++Il y a déjà des fonctions à l'intérieur pour réaliser des fonctions étendues,Réduire les dépendances externes,Il est également pratique de fusionner des espaces de noms plus tard.

Configurer le chemin du Journal

Easylogging++Prise en charge des profils、Le Code du programme configure le chemin du Journal de deux façons,Le chemin du journal est configuré ici comme un code de programme,Les codes sont les suivants::

static std::string LogRootPath = "D:\\Log";
static el::base::SubsecondPrecision LogSsPrec(3);
static std::string LoggerToday = el::base::utils::DateTime::getDateTime("%Y%M%d", &LogSsPrec); static void ConfigureLogger()
{
std::string datetimeY = el::base::utils::DateTime::getDateTime("%Y", &LogSsPrec);
std::string datetimeYM = el::base::utils::DateTime::getDateTime("%Y%M", &LogSsPrec);
std::string datetimeYMd = el::base::utils::DateTime::getDateTime("%Y%M%d", &LogSsPrec); std::string filePath = LogRootPath + "\\" + datetimeY + "\\" + datetimeYM + "\\";
std::string filename; el::Configurations defaultConf;
defaultConf.setToDefault();
//Utilisation recommandéesetGlobally
defaultConf.setGlobally(el::ConfigurationType::Format, "%datetime %msg");
defaultConf.setGlobally(el::ConfigurationType::Enabled, "true");
defaultConf.setGlobally(el::ConfigurationType::ToFile, "true");
defaultConf.setGlobally(el::ConfigurationType::ToStandardOutput, "true");
defaultConf.setGlobally(el::ConfigurationType::SubsecondPrecision, "6");
defaultConf.setGlobally(el::ConfigurationType::PerformanceTracking, "true");
defaultConf.setGlobally(el::ConfigurationType::LogFlushThreshold, "1"); //Limiter la configuration de la taille du fichier
//defaultConf.setGlobally(el::ConfigurationType::MaxLogFileSize, "2097152"); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Global)+".log";
defaultConf.set(el::Level::Global, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Debug) + ".log";
defaultConf.set(el::Level::Debug, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Error) + ".log";
defaultConf.set(el::Level::Error, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Fatal) + ".log";
defaultConf.set(el::Level::Fatal, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Info) + ".log";
defaultConf.set(el::Level::Info, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Trace) + ".log";
defaultConf.set(el::Level::Trace, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Warning) + ".log";
defaultConf.set(el::Level::Warning, el::ConfigurationType::Filename, filePath + filename); el::Loggers::reconfigureLogger("default", defaultConf); //Limiter la taille du fichier activer
//el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
}

Si vous voulez que chaque module fonctionnel du logiciel génère son propre journal,Vous pouvez vous référer au code ci - dessus pour l'implémenter vous - même,Notez les deux points suivants lors de la mise en œuvre:

  • Utiliser“%Y%M”Lors de la configuration du chemin de fichier,Easylogging++Seul le premier formateur sera reconnu,Par exemple:“\%datetime{%Y%M}\%datetime{%Y%M}”Le chemin généré est“\202108\%datetime{%Y%M}”.
  • Easylogging++L'ajout d'un niveau de log dans un nom de fichier n'est pas actuellement pris en charge,Besoin de se réaliser soi - même,Par exemple:“\%datetime{%Y%M}%level.log”Le chemin généré est“\202108%level.log”.

Ces questions peuvent être évitées comme je l'ai fait ci - dessus,Ou modifier le code source pour corriger,Les parties modifiées du code source seront placées à la fin de l'article.

Journal de défilement du temps

Easylogging++Il n'y a pas de fonction pour faire défiler les journaux dans le temps,Cette fonction doit vérifier l'heure actuelle et décider si un nouveau fichier journal doit être généré(Le nom du fichier doit contenir des informations temporelles),Il n'y a que deux questions clés:

  • Vérifiez l'heure:Sélectionnez vérifier une fois avant chaque écriture de journal,Il est donc nécessaire de surveiller l'écriture de chaque journal.
  • Générer un nouveau fichier journal:Appelez directement“ConfigureLogger()”La méthode écrase la configuration du Journal.

Note::Si vous utilisez un minuteur pour vérifier l'heure actuelle,Le fichier journal n'a pas pu être mis à jour en temps opportun lorsque l'heure du système a été modifiée.

Pour surveiller l'écriture de chaque journal, il faut mettre en oeuvre un héritageLogDispatchCallbackLa classe de,Les codes sont les suivants::

class LogDispatcher : public el::LogDispatchCallback
{
protected:
void handle(const el::LogDispatchData* data) noexcept override {
m_data = data;
// Utilisez le générateur de journaux par défaut de l'enregistreur pour programmer
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
m_data->dispatchAction() == el::base::DispatchAction::NormalLog)); //Vous pouvez également écrire dans la base de données ici
}
private:
const el::LogDispatchData* m_data;
void dispatch(el::base::type::string_t&& logLine) noexcept
{
el::base::SubsecondPrecision ssPrec(3);
static std::string now = el::base::utils::DateTime::getDateTime("%Y%M%d", &ssPrec);
if (now != LoggerToday)
{
LoggerToday= now;
ConfigureLogger();
}
}
};

LogDispatcherEst utilisé comme suit::

el::Helpers::installLogDispatchCallback<LogDispatcher>("LogDispatcher");
LogDispatcher* dispatcher = el::Helpers::logDispatchCallback<LogDispatcher>("LogDispatcher");
dispatcher->setEnabled(true);

Supprimer automatiquement le journal

La dernière modification sous le dossier supprimer automatiquement les journaux a eu lieu lenLe journal de l'autre jour,Les codes sont les suivants::

//Supprimer sous le chemin du fichiernLe fichier journal de l'autre jour,Les dossiers vides dus à la suppression des fichiers journaux sont supprimés la prochaine fois
//isRootPourtrueHeure,Seuls les sous - dossiers vides seront nettoyés
void DeleteOldFiles(std::string path, int oldDays, bool isRoot)
{
// Basé sur la date actuelle du système actuel/Temps
time_t nowTime = time(0);
//Gestion de fichiers
intptr_t hFile = 0;
//Informations sur le document
struct _finddata_t fileinfo;
//Extension de fichier
std::string extName = ".log";
std::string str;
//Est - ce un dossier vide
bool isEmptyFolder = true;
if ((hFile = _findfirst(str.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//Si c'est un catalogue,Itératif
//Si ce n'est pas le cas,,Vérifier les fichiers
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
isEmptyFolder = false;
DeleteOldFiles(str.assign(path).append("\\").append(fileinfo.name), oldDays, false);
}
}
else
{
isEmptyFolder = false;
str.assign(fileinfo.name);
if ((str.size() >= extName.size()) && (str.substr(str.size() - extName.size()) == extName))
{
//C'est un fichier journal
if ((nowTime - fileinfo.time_write) / (24 * 3600) > oldDays)
{
str.assign(path).append("\\").append(fileinfo.name);
system(("attrib -H -R " + str).c_str());
system(("del/q " + str).c_str());
} }
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile); if (isEmptyFolder && (!isRoot))
{
system(("attrib -H -R " + path).c_str());
system(("rd/q " + path).c_str());
}
}
}

L'opération de suppression à l'intérieur est réalisée en appelant la commande Batch,Il y a une commande par lots complète sur le Web pour supprimer automatiquement les fichiers périmés,Mais je n'ai jamais réussi.

La méthode delete peut être appelée chaque jour lors de la création d'un nouveau fichier journal,La suppression d'un fichier peut prendre un certain temps,Il vaut mieux rouvrir un fil,Les codes sont les suivants::

static int LogCleanDays = 30;
std::thread task(el::DeleteOldFiles, LogRootPath, LogCleanDays, true);

Encapsulé dans un fichier d'en - tête

Le code ci - dessus est assez fragmenté,Vous pouvez tout mettre sur“easylogginghelper.h”Dans le fichier d'en - tête,Ensuite, dans le projet, il est fait référence à.Le fichier d'en - tête fournit une fonction d'initialisation“InitEasylogging()”Pour initialiser toutes les configurations,Le Code du fichier d'en - tête est le suivant:

#pragma once
#ifndef EASYLOGGINGHELPER_H
#define EASYLOGGINGHELPER_H
#include "easylogging++.h"
#include <io.h>
#include <thread> INITIALIZE_EASYLOGGINGPP namespace el
{
static int LogCleanDays = 30;
static std::string LogRootPath = "D:\\Log";
static el::base::SubsecondPrecision LogSsPrec(3);
static std::string LoggerToday = el::base::utils::DateTime::getDateTime("%Y%M%d", &LogSsPrec); //Supprimer sous le chemin du fichiernLe fichier journal de l'autre jour,Les dossiers vides dus à la suppression des fichiers journaux sont supprimés la prochaine fois
//isRootPourtrueHeure,Seuls les sous - dossiers vides seront nettoyés
void DeleteOldFiles(std::string path, int oldDays, bool isRoot)
{
// Basé sur la date actuelle du système actuel/Temps
time_t nowTime = time(0);
//Gestion de fichiers
intptr_t hFile = 0;
//Informations sur le document
struct _finddata_t fileinfo;
//Extension de fichier
std::string extName = ".log";
std::string str;
//Est - ce un dossier vide
bool isEmptyFolder = true;
if ((hFile = _findfirst(str.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//Si c'est un catalogue,Itératif
//Si ce n'est pas le cas,,Vérifier les fichiers
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
isEmptyFolder = false;
DeleteOldFiles(str.assign(path).append("\\").append(fileinfo.name), oldDays, false);
}
}
else
{
isEmptyFolder = false;
str.assign(fileinfo.name);
if ((str.size() > extName.size()) && (str.substr(str.size() - extName.size()) == extName))
{
//C'est un fichier journal
if ((nowTime - fileinfo.time_write) / (24 * 3600) > oldDays)
{
str.assign(path).append("\\").append(fileinfo.name);
system(("attrib -H -R " + str).c_str());
system(("del/q " + str).c_str());
} }
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile); if (isEmptyFolder && (!isRoot))
{
system(("attrib -H -R " + path).c_str());
system(("rd/q " + path).c_str());
}
}
} static void ConfigureLogger()
{
std::string datetimeY = el::base::utils::DateTime::getDateTime("%Y", &LogSsPrec);
std::string datetimeYM = el::base::utils::DateTime::getDateTime("%Y%M", &LogSsPrec);
std::string datetimeYMd = el::base::utils::DateTime::getDateTime("%Y%M%d", &LogSsPrec); std::string filePath = LogRootPath + "\\" + datetimeY + "\\" + datetimeYM + "\\";
std::string filename; el::Configurations defaultConf;
defaultConf.setToDefault();
//Utilisation recommandéesetGlobally
defaultConf.setGlobally(el::ConfigurationType::Format, "%datetime %msg");
defaultConf.setGlobally(el::ConfigurationType::Enabled, "true");
defaultConf.setGlobally(el::ConfigurationType::ToFile, "true");
defaultConf.setGlobally(el::ConfigurationType::ToStandardOutput, "true");
defaultConf.setGlobally(el::ConfigurationType::SubsecondPrecision, "6");
defaultConf.setGlobally(el::ConfigurationType::PerformanceTracking, "true");
defaultConf.setGlobally(el::ConfigurationType::LogFlushThreshold, "1"); //Limiter la configuration de la taille du fichier
//defaultConf.setGlobally(el::ConfigurationType::MaxLogFileSize, "2097152"); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Global)+".log";
defaultConf.set(el::Level::Global, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Debug) + ".log";
defaultConf.set(el::Level::Debug, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Error) + ".log";
defaultConf.set(el::Level::Error, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Fatal) + ".log";
defaultConf.set(el::Level::Fatal, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Info) + ".log";
defaultConf.set(el::Level::Info, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Trace) + ".log";
defaultConf.set(el::Level::Trace, el::ConfigurationType::Filename, filePath + filename); filename = datetimeYMd + "_" + el::LevelHelper::convertToString(el::Level::Warning) + ".log";
defaultConf.set(el::Level::Warning, el::ConfigurationType::Filename, filePath + filename); el::Loggers::reconfigureLogger("default", defaultConf); //Limiter la taille du fichier activer
//el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck);
} class LogDispatcher : public el::LogDispatchCallback
{
protected:
void handle(const el::LogDispatchData* data) noexcept override {
m_data = data;
// Utilisez le générateur de journaux par défaut de l'enregistreur pour programmer
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
m_data->dispatchAction() == el::base::DispatchAction::NormalLog)); //Vous pouvez également écrire dans la base de données ici
}
private:
const el::LogDispatchData* m_data;
void dispatch(el::base::type::string_t&& logLine) noexcept
{
el::base::SubsecondPrecision ssPrec(3);
static std::string now = el::base::utils::DateTime::getDateTime("%Y%M%d", &ssPrec);
if (now != LoggerToday)
{
LoggerToday = now;
ConfigureLogger();
std::thread task(el::DeleteOldFiles, LogRootPath, LogCleanDays, true);
}
}
}; static void InitEasylogging()
{
ConfigureLogger(); el::Helpers::installLogDispatchCallback<LogDispatcher>("LogDispatcher");
LogDispatcher* dispatcher = el::Helpers::logDispatchCallback<LogDispatcher>("LogDispatcher");
dispatcher->setEnabled(true);
}
}
#endif

Vous n'avez besoin d'appeler qu'une seule fois“el::InitEasylogging();”C'est tout.,Les codes sont les suivants::

#include "easylogging++.h"
#include "easylogginghelper.h" int main()
{
el::InitEasylogging(); for (size_t i = 0; i < 10000; i++)
{
LOG(TRACE) << "***** trace log *****" << i;
LOG(DEBUG) << "***** debug log *****" << i;
LOG(ERROR) << "***** error log *****" << i;
LOG(WARNING) << "***** warning log *****" << i;
LOG(INFO) << "***** info log *****" << i;
//Ne pas utiliser facilement,Le programme va sortir
//LOG(FATAL) << "***** fatal log *****" << i;
Sleep(100);
}
}

Optimisation du code source(Non recommandé)

Ça dit:Easylogging++Seul le premier caractère de format temporel est reconnu et le caractère de format hiérarchique n'est pas reconnu,Il suffit de modifierTypedConfigurations::resolveFilenameL'implémentation de la fonction est juste,Les codes sont les suivants::

std::string TypedConfigurations::resolveFilename(Level level,const std::string& filename)
{
std::string resultingFilename = filename;
std::size_t dateIndex = std::string::npos;
std::string dateTimeFormatSpecifierStr = std::string(base::consts::kDateTimeFormatSpecifierForFilename);
//ifLire comme suit:while
while ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) {
while (dateIndex > 0 && resultingFilename[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1);
}
if (dateIndex != std::string::npos) {
const char* ptr = resultingFilename.c_str() + dateIndex;
// Goto end of specifier
ptr += dateTimeFormatSpecifierStr.size();
std::string fmt;
if ((resultingFilename.size() > dateIndex) && (ptr[0] == '{')) {
// User has provided format for date/time
++ptr;
int count = 1; // Start by 1 in order to remove starting brace
std::stringstream ss;
for (; *ptr; ++ptr, ++count) {
if (*ptr == '}') {
++count; // In order to remove ending brace
break;
}
ss << *ptr;
}
//Commentez cette déclaration
//resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count);
fmt = ss.str();
} else {
fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename);
}
base::SubsecondPrecision ssPrec(3);
std::string now = base::utils::DateTime::getDateTime(fmt.c_str(), &ssPrec);
base::utils::Str::replaceAll(now, '/', '-'); // Replace path element since we are dealing with filename
base::utils::Str::replaceAll(resultingFilename, dateTimeFormatSpecifierStr + "{"+ fmt+"}", now);
}
}
//Niveau de remplacement
base::utils::Str::replaceAll(resultingFilename, base::consts::kSeverityLevelFormatSpecifier, LevelHelper::convertToString(level));
base::utils::Str::replaceAll(resultingFilename, base::consts::kSeverityLevelShortFormatSpecifier, LevelHelper::convertToShortString(level));
return resultingFilename;
}

ModifierTypedConfigurations::resolveFilenameQuand la fonction est implémentée,.N'oubliez pas de modifier la définition dans le fichier d'en - tête et tous les appels à cette fonction.La modification directe du code source n'est pas recommandée,Modifier le code source n'est pas bon pour les mises à jour de version ultérieures.

Annexe

Easylogging++ Plus d'articles sur l'utilisation et l'extension de

  1. Asp.net BoilerplateDeAbpSessionExtension

    En coursAbpVersion1.2, Le type de projet est MVC5. Extensions sous forme d'attributs AbpSession,Et dans"Souviens - toi de moi."Après, La prochaine connexion automatique obtient également la valeur de la propriété étendue , Copyright attribué à " Le tableau blanc du coin "Bureau ...

  2. RepriseSQL Server Données effacées par erreur (Redimensionner)

    RepriseSQL Server Données effacées par erreur (Redimensionner) Tout le monde à mon article précédent <RepriseSQL Server Données effacées par erreur > La réaction a été très enthousiaste , Mais les procédures stockées dans cet article ne peuvent pas implémenter les données supprimées dans les sauvegardes de journaux sauvegardées ...

  3. .NET CoreEnregistrement des intergiciels et construction de pipelines(3) ---- UtiliserMap/MapWhenApproche élargie

    .NET CoreEnregistrement des intergiciels et construction de pipelines(3) ---- UtiliserMap/MapWhenApproche élargie 0x00 PourquoiMap(MapWhen)Extension Si la logique d'entreprise est plus simple , Un tuyau principal suffit , Ça ne marche pas ...

  4. .NET CoreEnregistrement des intergiciels et construction de pipelines(2)---- AvecUseMiddlewareMéthode d'extension enregistrement des classes d'intergiciels

    .NET CoreEnregistrement des intergiciels et construction de pipelines(2)---- AvecUseMiddlewareMéthode d'extension enregistrement des classes d'intergiciels 0x00 Pourquoi introduire une approche élargie Certains intergiciels ont des fonctions simples,Certains sont plus complexes,Et dépend d'autres composants.Sauf ...

  5. AdoptionEntityFramework.Extended C'est exact.EFPour agrandir(Entity Framework Extension de la série 2)

    Préface Entity Framework Extension du catalogue des séries Aujourd'hui, nous allons parler EntityFramework.Extended D'abord, la science populaire EntityFramework.ExtendedQu'est - ce que c'est?,Comme suit: Voilà. ...

  6. Dapper Extension ~~~Dapper.Contrib

    Qui peut résister à l'élan de la plate - forme ? Prends le tien. Net Va - t'en !http://www.cnblogs.com/dunitian/p/4822808.html#skill Article précédent:Dapper L'entrée contre le ciel ~Type fort, Type dynamique ...

  7. ExtJS 4.2 Date Extension des composants : Ajouter un bouton Clear

    ExtJS En plus de fournir des composants riches , Nous pouvons également étendre ses composants . Ici,Nous serons àDate Ajouter un [Effacer]Boutons, Pour effacer les valeurs sélectionnées pour ce composant . Table des matières 1. Date Introduction aux composants 2.  Description du Code principal 3. ...

  8. .NET Core Système de fichiers pour [5]: Système de fichiers étendu pour construire une version simple &ldquo;Disque Cloud&rdquo;

    FileProvider Construit un système de fichiers abstrait , Comme ses deux implémentations concrètes ,PhysicalFileProviderEtEmbeddedFileProvider Nous avons construit un système de fichiers physique et un texte intégré à l'assemblage pour nous ...

  9. Hawk 6. Compiler et étendre le développement

    Hawk C'est un projet Open Source , Pour que n'importe qui puisse contribuer au Code . Les auteurs sont également très heureux que les utilisateurs puissent étendre des plug - ins plus utiles . Compiler La compilation nécessite Visual Stuido, Version recommandée 2015, 2010 Et plus n'ont pas été testés , Mais ça devrait ...

  10. PourIEnumerable&lt;T&gt;AjouterRemoveAll&lt;IEnumerable&lt;T&gt;&gt;Approche élargie--Chapitre haute performance

    Écrivez le Code récemment , J'ai rencontré un problème , Microsoft est basé sur List<T> La façon dont vous l'apportez est public bool Remove(T item);, Mais parfois, on peut utiliser des choses comme RemoveAll<IEnumerab ...

Recommandation aléatoire

  1. À propos deLinux Erreur sous le système “ Nombre anormal de points flottants ( Core dumped )”Analyse de

    1. Découverte de problèmes Il y a ce code.: #include <stdio.h> int main() { int a, b, num1, num2, temp; printf("pleas ...

  2. js Fermeture automatique htmlÉtiquettes,Complément automatiquehtmlMarquage

    Si j'avais un DIV, Si ce n'est pas fermé, le style sera désordonné , Un tel code peut affecter les styles suivants , J'aimerais utiliser js Pour fermer automatiquement cette étiquette qui n'est pas fermée : Les codes sont les suivants:: 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  3. CI Note 1

    CodeIgniter Description CodeIgniter Oui.PHP Un ensemble fourni par les développeurs Web Kit d'application . Son but est de pouvoir Assez pour que vous puissiez terminer le projet plus rapidement que de commencer à zéro , Il offre une riche bibliothèque de classes pour répondre à nos besoins quotidiens De ...

  4. codeforce 630N Forecast

    N. Forecast time limit per test 0.5 seconds memory limit per test 64 megabytes input standard input ...

  5. [BZOJ 3585] mex 【 Équipe mo +En morceaux】

    Liens vers les sujets:BZOJ - 3585 Analyse du sujet Sectionmex, C'est - à - dire le plus petit nombre naturel qui n'apparaît pas dans l'intervalle . Donc nous utilisons une équipe mo + L'approche par blocs , Maintenir le nombre d'occurrences de chaque nombre dans l'intervalle courant en utilisant Mo . Et suppliemex Avec des blocs , Diviser les poids (Montrer ...

  6. selenium Plusieurs Threads ont démarré grid Cadre d'essai distribué encapsulé (Quatre)

    Neuf.Classe d'outils, Démarrer un navigateur pour tous les services à distance Inutils Créé dans le paquet javaCatégorie:LaunchAllRemoteBrowsers package com.lingfeng.utils; import java.n ...

  7. Correspondance des chaînes &mdash;KMP ExtensionKMP Manacher

    kuangbin Porte thématique à chaîne --http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview Modèle d'algorithme : KMP: ; ...

  8. div+css Les pages Web sont locales et téléchargées sur le serveur après IE11 Les effets sont différents ?

    div+css Les pages Web sont locales et téléchargées sur le serveur après IE11 Les effets sont différents ? La solution est htmlDehead Ajouter un paragraphe :<meta http-equiv="X-UA-Compatible&qu ...

  9. EthereumBootstrapEtKademlia Introduction à la logique de mise en oeuvre de l'algorithme (Basé surcpp-ethereum)

  10. VM_Centos7.3_X64_InstallationOracle12C Résumé des notes

    Déclaration: Cet article se réfère principalement au réseau original : Un.:InstallationCentos7.3 Machine virtuelle 1: Téléchargement du système d'exploitation CentOS 7 Adresse officielle de téléchargement :https://www.centos.org/download/ Description: Dans ce cas ...