//+------------------------------------------------------------------+ string get_header(string _filename) { int _fh = FileOpen(_filename, FILE_ANSI | FILE_COMMON | FILE_CSV | FILE_READ, "\n"); string header = FileReadString(_fh); FileClose(_fh); return header; } //+------------------------------------------------------------------+ int numero_lineas_csv(string _filename) { int lineas = 0; int _fh = FileOpen(_filename, FILE_ANSI | FILE_COMMON | FILE_CSV | FILE_READ, "\n"); while(!FileIsEnding(_fh)) { FileReadString(_fh); lineas++; } FileClose(_fh); return lineas; } //+------------------------------------------------------------------+ int numero_columnas_csv(string _filename) { int _fh = FileOpen(_filename, FILE_ANSI | FILE_COMMON | FILE_CSV | FILE_READ, "\n"); string linea = FileReadString(_fh); string columnas[]; StringSplit(linea, ',', columnas); FileClose(_fh); return ArraySize(columnas); } //+------------------------------------------------------------------+ matrix cargar_atributos_csv(string _filename, string &out_cabezera, int num_clases = 1) { int num_columnas = numero_columnas_csv(_filename); int num_lineas = numero_lineas_csv(_filename); matrix atributos(num_lineas - 1, num_columnas - num_clases); int _fh = FileOpen(_filename, FILE_ANSI | FILE_COMMON | FILE_CSV | FILE_READ, "\n"); if(_fh == INVALID_HANDLE) { Print(__FUNCTION__, "::Error: No se pudo abrir el archivo ", _filename); return atributos; } // Leer cabecera (ignorar) out_cabezera = FileReadString(_fh); int index = 0; while(!FileIsEnding(_fh)) { string linea = FileReadString(_fh); if(StringLen(linea) == 0) // Ignorar líneas vacías continue; string datos[]; StringSplit(linea, ',', datos); // Validar si la línea tiene el número esperado de columnas if(ArraySize(datos) != num_columnas) { Print("Advertencia: Línea mal formada en archivo CSV: ", linea); continue; } vector atributos_linea(num_columnas - num_clases); for(int i = 0; i < num_columnas - num_clases; i++) atributos_linea.Set(i, StringToDouble(datos[i])); atributos.Row(atributos_linea, index); index++; } FileClose(_fh); return atributos; } //+------------------------------------------------------------------+ //| Función para extraer una columna de un CSV | //+------------------------------------------------------------------+ string ExtractCSVColumn(string file_name, int col_index, ushort separator = ',') { string result = ""; string sym = ShortToString(separator); // Abrir el archivo CSV en modo lectura int handle = FileOpen(file_name, FILE_READ | FILE_CSV); if(handle == INVALID_HANDLE) { Print(__FUNCTION__, "::Error al abrir el archivo: ", file_name); return ""; } // Leer el archivo línea por línea hasta el final while(!FileIsEnding(handle)) { string line = FileReadString(handle); // Dividir la línea por comas en un arreglo de strings string columns[]; int count = StringSplit(line, separator, columns); // Verificar que la columna deseada exista en esta línea if(count > col_index) { // Si ya hay contenido en 'result', se añade una coma como separador if(result != "") result += sym; result += columns[col_index]; } } FileClose(handle); return result; } //+------------------------------------------------------------------+ matrix cargar_clases_csv(string _filename, int num_clases = 1) { int num_columnas = numero_columnas_csv(_filename); int num_lineas = numero_lineas_csv(_filename); matrix clases(num_lineas - 1, num_clases); int _fh = FileOpen(_filename, FILE_ANSI | FILE_COMMON | FILE_CSV | FILE_READ, "\n"); FileReadString(_fh); int index = 0; while(!FileIsEnding(_fh)) { vector clases_linea(num_clases); string linea = FileReadString(_fh); string datos[]; StringSplit(linea, ',', datos); for(int i = 0; i < num_clases; i++) { clases_linea.Set(i, StringToDouble(datos[num_columnas - num_clases + i])); } clases.Row(clases_linea, index); index++; } FileClose(_fh); return clases; } //+------------------------------------------------------------------+ struct file_data_csv { private: string file_cabezera; int file_handle; string file_name; bool create; public: void Create(string new_file_name, string cabezera, int open_flags = FILE_WRITE | FILE_CSV | FILE_COMMON) { this.file_name = new_file_name; this.file_cabezera = cabezera; this.file_handle = FileOpen(this.file_name, open_flags); create = true; if(this.file_handle == INVALID_HANDLE) { Print(__FUNCTION__"::Error al abrir el archivo: ", this.file_name, ", ultimo error: ", GetLastError()); } FileWrite(this.file_handle, cabezera); }; inline string GetFileName() { return this.file_name; } inline void Close() { FileClose(this.file_handle); } inline void Write(string text) { FileWrite(this.file_handle, text); } }; //+------------------------------------------------------------------+ void DeleteFileWithChecks(string fileName, int commonFlag = FILE_COMMON) { ResetLastError(); // Comprobar si el archivo existe en la ubicación especificada if(FileIsExist(fileName, commonFlag)) { // Intentar eliminar el archivo if(FileDelete(fileName, commonFlag)) { // Confirmación de que el archivo fue eliminado Print("Archivo '", fileName, "' eliminado correctamente."); } else { // Informar del error al intentar eliminar el archivo int errCode = GetLastError(); Print("Error al eliminar el archivo '", fileName, "'. Código de error: ", errCode); } } else { // El archivo no existe, informar al usuario Print("El archivo '", fileName, "' no existe en la ubicación especificada."); } } // Función para cambiar el nombre de un archivo en la carpeta de datos comunes o local void RenameFileWithChecks(const string oldFileName, int commonFlag, const string newFileName, int modeFlags) { // Comprobar si el archivo original existe if(FileIsExist(oldFileName, commonFlag)) { // Intentar cambiar el nombre del archivo if(FileMove(oldFileName, commonFlag, newFileName, modeFlags)) { // Confirmación de que el nombre del archivo fue cambiado Print("El archivo '", oldFileName, "' ha sido renombrado a '", newFileName, "' correctamente."); } else { // Informar del error al intentar cambiar el nombre del archivo int errCode = GetLastError(); Print("Error al cambiar el nombre del archivo de '", oldFileName, "' a '", newFileName, "'. Código de error: ", errCode); } } else { // El archivo no existe, informar al usuario Print("El archivo '", oldFileName, "' no existe en la ubicación especificada."); } } struct Filas { string datos[]; }; struct CSV { Filas data[]; }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CSVToArray(const string &fileName, bool common_flag, CSV &file, ushort line_separator, uint code_page = CP_ACP) { // Limpia el array existente ArrayResize(file.data, 0); int flags = common_flag ? FILE_COMMON : 0; // Verifica que el archivo exista if(!FileIsExist(fileName, flags)) { printf("%s:: El archivo %s no existe", __FUNCTION__, fileName); return false; // Sale de la función si el archivo no existe } flags = !common_flag ? (FILE_READ | FILE_CSV) : (FILE_READ | FILE_CSV | FILE_COMMON); ResetLastError(); // Abre el archivo en modo lectura const int fileHandle = FileOpen(fileName, flags, "\n", code_page); if(fileHandle == INVALID_HANDLE) { Print(__FUNCTION__, ":: Error al abrir el archivo: ", fileName, " | ultimo error: ", GetLastError()); return false; // Sale de la función si no se puede abrir el archivo } // Lee el archivo línea por línea while(!FileIsEnding(fileHandle)) { const string line = FileReadString(fileHandle); if(StringLen(line) > 0) { ArrayResize(file.data, file.data.Size() + 1); string linea[]; StringSplit(line, line_separator, linea); ArrayResize(file.data[file.data.Size() - 1].datos, linea.Size()); for(int i = 0; i < ArraySize(linea) ; i++) file.data[file.data.Size() - 1].datos[i] = linea[i]; } } // Cierra el archivo printf("%s:: Exito al cargar el archivo %s, numero de filas %d", __FUNCTION__, fileName, ArraySize(file.data)); FileClose(fileHandle); return true; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string StringTrim(const string text) { int start = 0; int end = StringLen(text) - 1; while(start <= end && StringGetCharacter(text, start) <= ' ') start++; while(end >= start && StringGetCharacter(text, end) <= ' ') end--; if(start > end) return ""; return StringSubstr(text, start, end - start + 1); } //+------------------------------------------------------------------+ string vector_to_string(const vector &v, string separator = ",") { string vector_str = ""; ulong length = v.Size(); for(ulong i = 0; i < length; i++) vector_str += DoubleToString(v[i], 14) + (i == length - 1 ? "" : separator); return vector_str; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ vector string_to_vector(const string str, ushort separator = ',') { string valores_linea[]; StringSplit(str, separator, valores_linea); int num_valores = ArraySize(valores_linea); vector v(num_valores); for(int i = 0; i < num_valores; i++) v[i] = StringToDouble(valores_linea[i]); return v; } //--- // Convierte un CSV en una matriz, opcionalmente saltando la cabecera bool CSVToMatrix(string fileName, matrix& out_mtx, bool common_flag, bool file_have_header, ushort line_separator, string &out_header) { // Limpia el array existente out_mtx.Resize(0, 0); // Verifica que el archivo exista int flags = common_flag ? FILE_COMMON : 0; if(!FileIsExist(fileName, flags)) { Print(__FUNCTION__, ":: El archivo ", fileName, " no existe"); return false; } ResetLastError(); // Abre el archivo en modo lectura CSV flags = common_flag == false ? (FILE_READ | FILE_CSV) : (FILE_READ | FILE_CSV | FILE_COMMON); int fileHandle = FileOpen(fileName, flags, "\n"); if(fileHandle == INVALID_HANDLE) { Print(__FUNCTION__, ":: Error al abrir el archivo: ", fileName, " | ultimo error: ", GetLastError()); return false; } // Si hay cabecera y no estamos al final, la leemos y descartamos if(file_have_header && !FileIsEnding(fileHandle)) { out_header =FileReadString(fileHandle); } int cols = 0; // Lee el resto del archivo línea por línea while(!FileIsEnding(fileHandle)) { string line = FileReadString(fileHandle); if(StringLen(line) == 0) // omite líneas vacías continue; // Añade una nueva fila a out_mtx out_mtx.Resize(out_mtx.Rows() + 1, out_mtx.Cols()); int row = (int)out_mtx.Rows() - 1; // Divide la línea según el separador string fields[]; StringSplit(line, line_separator, fields); // Ajusta el número de columnas y asigna los valores if(cols == 0) { out_mtx.Resize(out_mtx.Rows(), ArraySize(fields)); cols = ArraySize(fields); } vector v(ArraySize(fields)); if(v.Size() != cols) { printf("%s: Error critico la linea %s\n Es invalida el numero de columnas de esa fila es diferente a %I32d", __FUNCTION__, line, cols); continue; } for(int i = 0; i < ArraySize(fields); i++) v[i] = StringToDouble(fields[i]); out_mtx.Row(v, row); } // Cierra el archivo y retorna éxito FileClose(fileHandle); return true; } bool MatrixToCSV(string fileName, matrix &mtx, bool common_flag, string header, ushort line_separator = ',') { int flags = FILE_WRITE | FILE_CSV; if(common_flag) flags |= FILE_COMMON; // Abrir el archivo int file = FileOpen(fileName, flags, "\n"); if(file == INVALID_HANDLE) { Print(__FUNCTION__, " Error al abrir el archivo CSV: ", fileName); return false; } // Escribir encabezado si se proporciona if(StringLen(header) > 0) FileWriteString(file, header + "\n"); // Obtener dimensiones int rows = (int)mtx.Rows(); int cols = (int)mtx.Cols(); // Escribir los datos for(int i = 0; i < rows; i++) { string line = ""; for(int j = 0; j < cols; j++) { if(j > 0) line += ShortToString(line_separator); line += DoubleToString(mtx[i][j], 8); } FileWriteString(file, line + "\n"); } FileClose(file); Print(__FUNCTION__, " Exportación completada: ", fileName); return true; } //+------------------------------------------------------------------+ //| Extrae columnas especificadas de una matriz | //+------------------------------------------------------------------+ matrix ExtraerMaxtriDeMatrix(const matrix &m, ulong start_col, ulong end_col) { matrix out = { }; // Verifica rangos válidos if(start_col < 0 || end_col >= m.Cols() || start_col > end_col) { Print(__FUNCTION__, " Error: índices de columna inválidos."); return m; // retorna matriz vacía } // Número de filas y columnas que tendrá la nueva matriz ulong rows = m.Rows(); printf("%s | Numero de columnas totales %I64u | Start %I64u | End %I64u", __FUNCTION__, m.Cols(), start_col, end_col); // Copia los datos desde la matriz original a la matriz resultado for(ulong i = start_col ; i <= end_col; i++) { out.Resize(rows, out.Cols() + 1); vector c = m.Col(i); out.Col(c, out.Cols() - 1); } return out; } //+------------------------------------------------------------------+