Depuración personalizada en Sublime Text usando C++ para programación competitiva

  • La Programación Competitiva es un deporte mental que nos permite codificar un problema dado bajo las restricciones establecidas. El propósito de este artículo es guiar a cada individuo sobre cómo pueden depurar su código de manera eficiente durante un concurso.

Requisito previo: Configuración de Sublime Text para el entorno de programación competitivo de C++

El tiempo es algo precioso e importa mucho durante un concurso de codificación. Al escribir un código, surgen errores y los programadores suelen pasar mucho tiempo depurándolo. A menudo, los programadores se ocupan de estructuras de datos complejas durante un concurso y es necesario depurarlas en el tiempo límite. 

Este artículo se enfoca en cómo depurar el código fuente de C++ de manera eficiente en Sublime Text (IDE) durante un concurso y ahorrar tiempo. En primer lugar, se requiere configurar la estructura de archivos de nuestro Sublime Text. A continuación se muestran los pasos para configurar la estructura de archivos de Sublime Text.  

Paso 1: Abra Sublime Text y siga los pasos a continuación:

1. Crea tres archivos:

  • file.cpp: El archivo para escribir el código.
  • inputf.txt: El archivo donde estaremos dando la entrada.
  • outputf.txt: El archivo donde se mostrará la salida.

2. Ahora, realiza los siguientes pasos:

  • Seleccione Ver > Diseño > Columnas: 3 . Esto creará tres columnas en el espacio de trabajo. Mueva los tres archivos en tres columnas.
  • Seleccione Ver > Grupos > Máximo de columnas: 2: input.txt y output.txt se apilarán en una sola columna.

Su Sublime Text se vería similar a esto:

Paso 2: crea una función local fuera de la función principal. Se utiliza para recibir entradas del archivo input.txt y mostrar la salida en el archivo output.txt. A continuación se muestra el fragmento de código C++ para el mismo.

C++

// Declare this function outside
// the main function
void local()
{
  // In case of online judges (like
  // codechef, codeforces etc) these
  // lines will be skipped. In other
  // words these lines would be executed
  // in Sublime Text only
  #ifndef ONLINE_JUDGE
 
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
 
  // ONLINE_JUDGE
  #endif
}

 
Paso 3: Llamar desde la función principal: 

// Call from the main function
local();

Combinando los pasos anteriores nuestro programa completo sería:

C++

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Local function
void local()
{
  #ifndef ONLINE_JUDGE
  freopen("input.txt",
          "r", stdin);
  freopen("output.txt",
          "w", stdout);
   
  // ONLINE_JUDGE
  #endif
}
 
// Driver code
int main()
{
  local();
  return 0;
}

 
Paso 4: Ahora el IDE se vería similar a esto:

Depuración usando la función de impresión:

Cree una función de impresión en nuestro programa cada vez que necesitemos imprimir una variable o cualquier estructura de datos como vector, conjunto, mapa, etc. A continuación se muestra el programa C++ para implementar el mismo enfoque:

C++

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Driver code
int main()
{
  // Initializing a vector
  vector<int> vect = {2, 4, 10,
                      12, 17};
 
  // First operation
  for (auto& x : vect)
  {
    if (x % 2 == 0)
      x += 10;
    else
      x -= 10;
  }
 
  // Second operation
  for (auto& x : vect)
    x += 2;
 
  // Third operation
  for (auto& x : vect)
    x += 20;
}

Supongamos que algo salió mal en nuestra lógica debido a que no se obtiene el resultado deseado durante un concurso y, por lo tanto, para verificar el estado del vector después de la primera operación, se puede crear una función de impresión fuera de la función principal que acepta un vector.

C++

// print function outside the
// main function
void print(vector<int>& vect)
{
  cout << "vect " << ' ';
  cout << '[' << ' ';
 
  // Print vector elements
  for (auto x : vect)
  {
    cout << x << ' ';
  }
  cout << ']';
}

 
Siempre que sea necesario comprobar los elementos del vector, se puede llamar a la función imprimir() pasando el vector como argumento a la función de impresión.

// Calling print function from main

print(vect);

A continuación se muestra el programa C++ completo para ilustrar cómo implementar el concepto anterior:

C++

// C++ program to implement
// the above concept
#include <bits/stdc++.h>
using namespace std;
 
// Print function for debugging
void print(vector<int>& vect)
{
  cout << "vect " << ' ';
  cout << '[' << ' ';
 
  // Print vector elements
  for (auto x : vect)
  {
    cout << x << ' ';
  }
  cout << ']';
}
 
// Driver code
int main()
{
  // Initializing a vector
  vector<int> vect = {2, 4, 10,
                      12, 17};
 
  // First operation
  for (auto& x : vect)
  {
    if (x % 2 == 0)
      x += 10;
    else
      x -= 10;
  }
 
  // Printing vect elements after
  // applying first operation
  // Checking the status of vect as
  // a part of debugging
  print(vect);
 
  // Second operation
  for (auto& x : vect)
    x += 2;
 
  // Third operation
  for (auto& x : vect)
    x += 20;
 
  int finalAnswer = 0;
  for (auto x : vect)
    finalAnswer += x;
 
  // Print the final answer
  cout << "\nFinal Answer: " <<
            finalAnswer;
  return 0;
}
Producción

vect  [ 12 14 20 22 7 ]
Final Answer: 185

Desventajas de este método: 

  • Para la misma estructura de datos pero con diferentes tipos de datos, es necesario crear múltiples funciones de impresión. Por ejemplo, hay un vector de tipo entero y un vector de tipo string, luego para imprimir elementos, se requiere crear dos funciones de impresión fuera de la función principal. Una función de impresión aceptará un vector de tipo entero y otra función de impresión aceptará un vector de tipo string.
  • El contenido del vector se imprimiría junto con los valores deseados en el mismo archivo output.txt, lo que podría ser confuso para nosotros.
  • Es necesario comentar las declaraciones que se utilizan para llamar a una función de impresión desde la función principal, antes de enviar el archivo de código fuente al juez en línea (Codeforces, Spoj, Codechef, etc.).

Depuración usando plantilla:

En el método anterior, el tipo de datos del vector está codificado. La plantilla se puede utilizar en C++. Una plantilla es una herramienta simple pero muy poderosa en C++. La idea simple es pasar el tipo de datos como un parámetro para que no haya necesidad de escribir el mismo código (función de impresión) para diferentes tipos de datos. A continuación se muestra el fragmento de código C++ para la plantilla:

C++

// One print function works for
// all data types.  This would work
// even for user defined types if
// operator '>' is overloaded
template <typename T>
 
void print(vector<T> vect)
{
    // body
}

 
A continuación se muestra el programa completo en C++ para ilustrar el concepto anterior:

C++

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Using template so that this
// function works for all data
// types
template <typename T> void print(
          vector<T>& vect)
{
  cout << "vect " << ' ';
  cout << '[' << ' ';
 
  for (auto x : vect)
  {
    cout << x << ' ';
  }
  cout << ']';
  cout << '\n';
}
 
// Driver code
int main()
{
  vector<int> vect1 = {2, 4, 10,
                       12, 17};
 
  for (auto& x : vect1)
  {
    if (x % 2 == 0)
      x += 10;
    else
      x -= 10;
  }
 
  // Printing vect1 elements
  print(vect1);
 
  // Initializing a vector of
  // string type
  vector<string> vect2 = {"Geeks",
                          "for", "Geeks"};
 
  // Printing vect2 elements
  print(vect2);
 
  // Modifying vect2
  // push back string "is great"
  vect2.push_back("is the great");
 
  // Printing vect2 after modification
  print(vect2);
 
  int finalAnswer = 0;
  for (auto x : vect1)
    finalAnswer += x;
  cout << "Final Answer: " <<
           finalAnswer;
  return 0;
}
Producción

vect  [ 12 14 20 22 7 ]
vect  [ Geeks for Geeks ]
vect  [ Geeks for Geeks is the great ]
Final Answer: 75

Se puede hacer algo similar con cualquier estructura de datos como un conjunto , un conjunto múltiple , pares , etc. A continuación se muestra la implementación usando el conjunto:

C++

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Using template so that this
// function works for all data
// types
template <typename T> void print(
          set<T>& set1)
{
  cout << "set " << ' ';
  cout << '[' << ' ';
 
  for (auto x : set1)
  {
    cout << x << ' ';
  }
  cout << ']';
  cout << '\n';
}
 
// Driver code
int main()
{
  // Declaring a set
  set<int> set1;
 
  // Inserting elements in the set
  for (int i = 0; i < 10; i++)
    set1.insert(i);
 
  // Printing set1 elements
  print(set1);
 
  // Declaring another set of
  // string type
  set<string> set2;
 
  // Inserting elements in the set
  set2.insert("GeeksforGeeks");
 
  // Printing set2 elements
  print(set2);
 
  int finalAnswer = 0;
   
  for (auto x : set1)
    finalAnswer += x;
  cout << "Final Answer: " <<
           finalAnswer;
  return 0;
}
Producción

set  [ 0 1 2 3 4 5 6 7 8 9 ]
set  [ GeeksforGeeks ]
Final Answer: 45

Desventajas de este método: 

  • El método anterior no es muy eficiente ya que cada vez que se envía el programa, es necesario comentar las declaraciones de impresión dentro de la función principal.
  • Los elementos de la estructura de datos se imprimirían junto con otros valores deseados en el mismo archivo output.txt, lo que podría ser confuso para nosotros.

Depuración usando cerr:

La idea es usar la combinación de cerr   (flujo de error) y manejo de archivos en el programa. Cree un archivo separado (error.txt) y use cerr stream en lugar de cout stream. Finalmente, con la ayuda del manejo de archivos, imprima el estado de la estructura de datos en el archivo error.txt.

Paso 1: en primer lugar, agregue los siguientes fragmentos fuera de la función principal:

  • Para imprimir una variable , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T>
 
//Function to print the variable
void print(T x)
{
  // Using error stream to print
  // the variable
  cerr << x;
}
  • Para imprimir elementos vectoriales , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T>
 
// Function to print the elements
// of the vector
void print(vector<T>& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same to print a variable (Function
    // Overloading)
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos establecidos dispuestos en orden no descendente, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T>
 
// Function to print elements of the
// set arranged in non-descending order
void print(set<T>& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as printing a variable
    // (Function Overloading)
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos establecidos dispuestos en orden no ascendente, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

template <typename T>
 
// Function to print the set elements
// arranged in non-ascending order
void print(set<T, greater<T> >& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // same as printing a variable
    // (Function Overloading)
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos de conjuntos desordenados , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T>
 
// Function to print unordered
// set elements
void print(unordered_set<T>& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as printing a variable
    // Using the concept of function
    // overloading
    print(x);
     
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos del mapa , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T, typename V>
 
//Function to print map elements
// arranged in non-descending order
void print(map<T, V>& a)
{
  cerr << "[ ";
 
  for (auto i : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(i);
 
    cerr << " ";
  }
  cerr << "]";
}
  • Para imprimir elementos de mapa desordenados , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T, typename V>
 
//Function to print unordered map elements
void print(unordered_map<T, V>& a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(i);
     
    cerr << " ";
  }
  cerr << "]";
}
  • Para imprimir elementos de conjuntos múltiples organizados en orden no descendente, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T>
 
//Function to print multiset elements
// arranged in non-descending order
void print(multiset<T>& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos de conjuntos múltiples , dispuestos en orden no ascendente, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

//Template definition
template <typename T>
 
//Function to print elements of a
// multiset arranged in non-ascending order
void print(multiset<T, greater<T> >& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos de conjuntos desordenados , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T>
 
// Print function to print unordered
// set elements
void print(unordered_set<T>& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(x);
 
    cerr << ' ';
  }
  cerr << ']';
}
  • Para imprimir elementos vectoriales de vectores , podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T>
 
// Function to print vector of
// vectors elements
void print(vector<vector<T> >& a)
{
  cerr << "[ ";
 
  for (auto i : a)
  {
    // Same as variable using the
    // concept of function overloading
    print(i);
     
    cerr << " ";
  }
  cerr << "]";
}
  • Para imprimir un par de elementos, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T, typename V>
 
// Function to print elements of a pair
void print(pair<T, V> x)
{
  // Sam as printing the variable using
  // the concept of function overloading
  print(x.ff);
   
  cerr << ':';
 
  // Same as variable using the concept
  // of function overloading
  print(x.ss);
}
  • Para imprimir un par de elementos vectoriales, podemos crear una función de impresión con una definición de plantilla justo encima de la función:

C++

// Template definition
template <typename T, typename V>
 
// Function to print vector of
// pairs elements
void print(vector<pair<T, V> >& a)
{
  cerr << '[' << ' ';
 
  for (auto x : a)
  {
    // Same as printing a variable using
    // the concept of function overloading
    print(x.ff);
    cerr << ":";
 
    // Same as printing a variable using
    // the concept of function overloading
    print(x.ss);
    cerr << ' ';
  }
  cerr << ']';
}

 
Paso 2: cree un archivo nuevo más ( error.txt ) y asegúrese de que esté en la misma carpeta.

Archivo error.txt: todos los elementos de las estructuras de datos que hemos mencionado en los fragmentos anteriores se imprimirán en este archivo de texto solo sin afectar el archivo output.txt.

Tenga en cuenta que queremos escribir en este archivo usando flujo de error (cerr). Nuevamente, se puede tomar la ayuda de las directivas de preprocesador ifndef y endif .

C++

// We want to skip writing on error.txt
// file when online judge (Codechef,
// Codeforces, etc) is defined
#ifndef ONLINE_JUDGE
    freopen("error.txt", "w", stderr);
 
// ONLINE_JUDGE
#endif

Después de agregar las líneas anteriores en nuestra función local, la función completa se convierte en:

C++

// Now local function would look like:
void local()
{
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
   
  // ONLINE_JUDGE
  #endif
 
  // It basically means that these
  // statements (Between ifndef and
  // endif) would be skipped / ignored
  // if ONLINE_JUDGE is defined We don't
  // need to comment "local();" statement
  // in our function while submitting our
  // source code file to online judges.
  // It would be handled automatically
 
  #ifndef ONLINE_JUDGE
  freopen("error.txt", "w", stderr);
   
  // ONLINE_JUDGE
  #endif
}

Paso 3: Además, no queremos comentar las declaraciones de depuración (estructura_datos) al enviar el archivo de código fuente a los jueces en línea. En palabras simples, existe la necesidad de encontrar una manera de que las funciones de depuración funcionen para el texto sublime (IDE) pero serían omitidas/ignoradas por los jueces en línea.
Nuevamente, esto se puede lograr usando las directivas de preprocesador ifndef y endif nuevamente en el código fuente.

C++

// If online judge is defined
#ifndef ONLINE_JUDGE
#define debug(x)                                          
cerr << #x << "  ";                                   
print(x);                                            
cerr << '\n';
 
// If Online Judge is not defined
#else
#define debug(x)
#endif

 
Ahora el IDE se vería similar a esto:

Sublime Text

Paso 4: Siempre que exista la necesidad de verificar el estado de cualquier estructura de datos, se puede realizar la siguiente llamada:

// Calling from the main function
debug(dataStructure);

Paso 5: A continuación se muestra la implementación del método anterior:

Ejemplo 1:

C++

/* It is recommended below snippets in
   your template file of competitive programming */
#include <bits/stdc++.h>
using namespace std;
 
// Debugging Functions
 
template<class T>void print(T x)
{
  cerr << x;
}
template<class T, class V>
         void print(pair<T , V> x)
{
  print(x.ff);
  cerr << ':';
  print(x.ss);
}
template<class T>
         void print(vector<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(set<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(set<T,
                    greater<T>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(multiset<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(multiset<T,
                    greater<T>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(unordered_set<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T, class V>
         void print(vector<pair<T, V>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x.ff);
    cerr << ":";
    print(x.ss);
    cerr << ' ';
  }
  cerr << ']';
}
template <class T, class V>
          void print(map <T, V> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
template <class T, class V>
          void print(unordered_map <T, V> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
template <class T>
          void print(vector<vector<T>> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
 
void local()
{
  // ONLINE_JUDGE
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif
 
  // ONLINE_JUDGE
  #ifndef ONLINE_JUDGE
  freopen("error.txt", "w", stderr);
  #endif
 
  #ifndef ONLINE_JUDGE
  #define debug(x)
  cerr << #x << "  ";
  print(x);
  cerr << '\n';
  #else
  #define debug(x)
  #endif
}
 
// Driver code
int main()
{
  local();
 
  // Number of elements in the vector
  int n;
 
  // Taking input from the user
  // through input.txt file
  cin >> n;
 
  // Declaring a vector of integer
  // type of size n
  vector<int> vect1(n);
 
  // Initializing the vector   
  for(int i = 0 ; i < n ; i++)
    cin >> vect1[i];
 
  // Modifying the vector
  for (auto& x : vect1)
  {
    if (x % 2 == 0)
      x += 10;
    else
      x -= 10;
  }
 
  // Printing vect1 elements
  // It will be printed in error.txt
  // file using cerr stream
  debug(vect1);
 
  // Initializing a vector of string type
  vector<string> vect2 = {"Geeks", "for", "Geeks"};
 
  // Printing vect2 elements
  // It will be printed in error.txt
  // file using cerr stream
  debug(vect2);
 
  // Modifying vect2
  // push back string "is great"
  vect2.push_back("is the great");
 
  // Printing vect2 after modification
  // It will be printed in error.txt
  // file using cerr stream
  debug(vect2);
 
  // Calculating the answer
  int finalAnswer = 0;
  for (auto x : vect1)
    finalAnswer += x;
 
  // Finally, printing answer in output.txt
  // file using cout stream
  cout << "Final Answer: " << finalAnswer;
 
  return 0;
}

archivo.cpp archivo:

file.cpp

archivo de entrada.txt

input.txt

archivo de salida.txt 

output.txt

archivo error.txt

error.txt

Ejemplo 2:

C++

/* It is recommended below snippets in
   your template file of competitive programming */
 
#include <bits/stdc++.h>
using namespace std;
 
// Debugging Functions
template<class T>void print(T x)
{
  cerr << x;
}
template<class T , class V>
         void print(pair<T, V> x)
{
  print(x.ff);
  cerr << ':';
  print(x.ss);
}
template<class T>
         void print(vector<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(set<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(set<T,
                    greater<T>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(multiset<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(multiset<T,
                    greater<T>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T>
         void print(unordered_set<T> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x);
    cerr << ' ';
  }
  cerr << ']';
}
template<class T, class V>
         void print(vector<pair<T, V>> &a)
{
  cerr << '[' << ' ';
  for(auto x : a)
  {
    print(x.ff);
    cerr << ":";
    print(x.ss);
    cerr << ' ';
  }
  cerr << ']';
}
template <class T, class V>
          void print(map <T, V> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
template <class T, class V>
          void print(unordered_map <T, V> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
template <class T>
          void print(vector<vector<T>> &a)
{
  cerr << "[ ";
  for (auto i : a)
  {
    print(i);
    cerr << " ";
  }
  cerr << "]";
}
 
void local()
{
  // ONLINE_JUDGE
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif
 
  // ONLINE_JUDGE
  #ifndef ONLINE_JUDGE
  freopen("error.txt", "w", stderr);
  #endif
 
  #ifndef ONLINE_JUDGE
  #define debug(x)
  cerr << #x << "  ";
  print(x);
  cerr << '\n';
  #else
  #define debug(x)
  #endif
}
 
// Driver code
int main()
{
  local();
 
  // Number of elements in the set
  int n;
 
  // Taking input from the user
  // through input.txt file
  cin >> n;
 
  // Declaring a set of integers
  set<int> set1;
 
  for(int i = 0 ; i < n ; i++)
  {
    int number;
 
    // Taking input from the user
    // through input.txt file
    cin >> number;
     
    //Inserting in the set
    set1.insert(number);  
  }   
 
 
  // Erasing from the set
  if(!set1.empty())
  {
    // erasing the first element
    // of the set
    set1.erase(set1.begin());
  }
 
  // Printing set1 elements
  // It will be printed in error.txt
  // file using cerr stream
  debug(set1);
 
  // Declaring another set
  set<string> set2;
 
  // Inserting in the set
  set2.insert("GeeksforGeeks");
 
  // Printing set2 elements
  // It will be printed in error.txt file
  // using cerr stream
  debug(set2);
 
  // Inserting in set
  // Insert the string "is great"
  set2.insert("Geek");
 
  // Printing set2 elements after
  // inserting into the set, It will
  // be printed in error.txt file
  // using cerr stream
  debug(set2);
 
  // Calculating the answer
  int finalAnswer = 0;
  for (auto x : set1)
    finalAnswer += x;
 
  // Finally, printing answer in output.txt
  // file using cout stream
  cout << "Final Answer: " << finalAnswer;
 
  return 0;
}

archivo.cpp archivo:

file.cpp

archivo de entrada.txt

input.txt

archivo de salida.txt
 

output.txt

archivo error.txt

error.txt

Ventaja de este método de depuración:

  • Ahora no es necesario comentar cada una de las declaraciones de depuración en el programa antes de enviar el archivo de código fuente a los jueces en línea.
  • La estructura de datos o los elementos STL se imprimirían en un archivo separado (error.txt) y los valores de salida deseados se imprimirían en el archivo output.txt, haciéndolo más legible.
  • En pocas palabras, esto puede ahorrar mucho tiempo durante un concurso de codificación.

Publicación traducida automáticamente

Artículo escrito por bhuwanesh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *