Mi opinión personal: Un programa como éste yo lo haría siempre en C. Si quiero compilar con un compilador de C++ cambiaría las cabeceras a <cstdio>, <cstdlib>, etc., y listo.
¿La razón? Como bien dijo un autor que respeto, C es un lenguaje intencionalmente escueto. Se maneja con un conjunto mínimo de funciones de la biblioteca estándar. Ese conjunto está reducido a ta punto que es difícil lograr que la tarea de una función la realice otra (salvo algunas excepciones de <stdio.h> como usar fgetc(stdin) en lugar de getchar()), es decir, prácticamente las funciones de su biblioteca estándar no se duplican. De hecho, no hay duplicidad en el ejemplo que cité, porque sólo existe fgetc como función de biblioteca mientras getchar() está implementado como una macro a partir de aquélla.
Yo creo que no se puede decir lo mismo de C++. El mundo en este lenguaje es inmenso. Hay clases y métodos para todos gustos, tamaños y colores. Lo cual puede ser abrumante.
Me explico mejor, supóngase que un programador principiante busca ayuda en internet sobre un código que realice determinada tarea en C. Por ejemplo: "leer un fichero de texto y escribir su contenido en otro fichero, convertiendo las palabras a mayúsculas". Si el código es "óptimo" o "correcto", y se limita a la biblioteca estándar, lo más probable es que al menos el 50% de los resultados de su búsqueda sean similares o muy similares entre sí. Es que C es tan mínimo que casi hay una sola manera "perfecta" de hacer las cosas. Cuando mucho dos.
Si buscas lo mismo en C++, creo que habrá mucha más variedad y diversidad de maneras de resolver el problema (con o sin flujos, usando o no la clase string, etc.). Entonces, el principiante de 10 resultados que busca en internet para este problema, ¡ encuentra 10 soluciones diferentes ! Y Aquí empieza a embromarse. ¿cuál es mejor, cuál es peor, por qué una y no la otra?
Simplemente uso C++ cuando se requieren clases, de otro modo para operaciones básicas de procesar cadenas, números, ficheros, E/S por consola, etc., me remito a C. No se si estas opiniones son porque me gusta llegar a la forma más simple y breve de resolver las cosas, o porque soy un romántico que decidió apegarse al pasado de C, jejeje.
En cuanto a tu programa, me permito algunas recomendaciones para perfeccionarlo:
(1) Abre el fichero que entrada en modo de solo lectura:
fichero = fopen( nombre, "r" )
con "r" en lugar de "r+".
(2) Abre el fichero de salida en modo de escritura:
fichero2 = fopen( nombre2, "w")
(3) Para leer una línea del flujo, puedes usar la función fgets(char *buffer, int n, FILE *stream). El primer argumento buffer debe ser un arreglo de char, de al menos n caracteres de capacidad. El segundo argumento es uno más que los caracteres a leer (se deja uno más, para que fgets() coloque automáticamente el nulo de terminación). El tercer argumento es el apuntador a archivo abierto. Ten en cuenta que el salto de línea '\'n se copia al arreglo sólo si tiene espacio "para caber", o sea, si la cantidad de caracteres leídos antes de él es menor a (n-1). Además, si fgets() no pudo leer (si encuentra el fin de archivo), devuelve NULL.
Te preparé un sencillo código que abre el fichero como lectura, toma sus líneas y las escribe al fichero2, además imprime por pantalla lo que va leyendo para verificar como marcha del programa.
Para el fichero de entrada:
Hola
Mundo
Hugo Paco Luis
el programa produce la salida:
Nota que al final imprime una línea vacía, ésto es porque el fichero está terminado en un return (un '\n'). Se podría eliminar ese defecto inspeccionando el contenido copiado al buffer. El valor de retorno de main() en caso de error es -1, que es más usual en lugar de 1.
==================
NOTAS. Una alternativa más breve a:
fichero = fopen( nombre, "r" );
if ( fichero == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre ); /* error */
return -1;
}
es:
if ( ( fichero = fopen( nombre, "r" ) ) == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre ); /* error */
return -1;
}
¿La razón? Como bien dijo un autor que respeto, C es un lenguaje intencionalmente escueto. Se maneja con un conjunto mínimo de funciones de la biblioteca estándar. Ese conjunto está reducido a ta punto que es difícil lograr que la tarea de una función la realice otra (salvo algunas excepciones de <stdio.h> como usar fgetc(stdin) en lugar de getchar()), es decir, prácticamente las funciones de su biblioteca estándar no se duplican. De hecho, no hay duplicidad en el ejemplo que cité, porque sólo existe fgetc como función de biblioteca mientras getchar() está implementado como una macro a partir de aquélla.
Yo creo que no se puede decir lo mismo de C++. El mundo en este lenguaje es inmenso. Hay clases y métodos para todos gustos, tamaños y colores. Lo cual puede ser abrumante.
Me explico mejor, supóngase que un programador principiante busca ayuda en internet sobre un código que realice determinada tarea en C. Por ejemplo: "leer un fichero de texto y escribir su contenido en otro fichero, convertiendo las palabras a mayúsculas". Si el código es "óptimo" o "correcto", y se limita a la biblioteca estándar, lo más probable es que al menos el 50% de los resultados de su búsqueda sean similares o muy similares entre sí. Es que C es tan mínimo que casi hay una sola manera "perfecta" de hacer las cosas. Cuando mucho dos.
Si buscas lo mismo en C++, creo que habrá mucha más variedad y diversidad de maneras de resolver el problema (con o sin flujos, usando o no la clase string, etc.). Entonces, el principiante de 10 resultados que busca en internet para este problema, ¡ encuentra 10 soluciones diferentes ! Y Aquí empieza a embromarse. ¿cuál es mejor, cuál es peor, por qué una y no la otra?
Simplemente uso C++ cuando se requieren clases, de otro modo para operaciones básicas de procesar cadenas, números, ficheros, E/S por consola, etc., me remito a C. No se si estas opiniones son porque me gusta llegar a la forma más simple y breve de resolver las cosas, o porque soy un romántico que decidió apegarse al pasado de C, jejeje.
En cuanto a tu programa, me permito algunas recomendaciones para perfeccionarlo:
(1) Abre el fichero que entrada en modo de solo lectura:
fichero = fopen( nombre, "r" )
con "r" en lugar de "r+".
(2) Abre el fichero de salida en modo de escritura:
fichero2 = fopen( nombre2, "w")
(3) Para leer una línea del flujo, puedes usar la función fgets(char *buffer, int n, FILE *stream). El primer argumento buffer debe ser un arreglo de char, de al menos n caracteres de capacidad. El segundo argumento es uno más que los caracteres a leer (se deja uno más, para que fgets() coloque automáticamente el nulo de terminación). El tercer argumento es el apuntador a archivo abierto. Ten en cuenta que el salto de línea '\'n se copia al arreglo sólo si tiene espacio "para caber", o sea, si la cantidad de caracteres leídos antes de él es menor a (n-1). Además, si fgets() no pudo leer (si encuentra el fin de archivo), devuelve NULL.
Te preparé un sencillo código que abre el fichero como lectura, toma sus líneas y las escribe al fichero2, además imprime por pantalla lo que va leyendo para verificar como marcha del programa.
Código (cpp) [Seleccionar]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main( ) {
FILE *fichero;
FILE *fichero2;
char buffer[1001]; /* bufer de linea, 1000 caracteres */
char nombre[11] = "datos.txt";
char nombre2[11]= "salida.txt";
fichero = fopen( nombre, "r" ); // Fichero datos.txt desde el que leo los datos.
fichero2= fopen( nombre2, "w"); // Fichero salida.txt donde escribire los datos.
if ( fichero == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre ); /* error */
return -1;
}
if ( fichero2 == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre2 ); /* error */
return -1;
}
/* Mensaje al usuario */
printf( "\nLeyendo los datos del fichero \"%s\":\n", nombre );
/* Leer linea a linea, ponerlo en buffer y pasarlo al fichero2 convertido
* a mayusculas */
linea = 1;
while ( !feof(fichero) ) {
if ( fgets( buffer, 1001, fichero ) != NULL )
printf("Linea %d: \n\t%s", linea++, buffer );
}
/* cerramos los ficheros abiertos */
if( !fclose(fichero) )
printf( "Fichero '%s' cerrado con exito\n", nombre );
else
{
printf( "Error: fichero '%s' NO CERRADO\n", nombre );
return -1;
}
if( !fclose(fichero2) )
printf( "Fichero '%s' cerrado con exito\n", nombre2 );
else
{
printf( "Error: fichero '%s' NO CERRADO\n", nombre2 );
return -1;
}
getchar();
return 0;
}
Para el fichero de entrada:
Hola
Mundo
Hugo Paco Luis
el programa produce la salida:
Código [Seleccionar]
Leyendo los datos del fichero "datos.txt":
Linea 1:
Hola
Linea 2:
Mundo
Linea 3:
Hugo Paco Luis
Linea 4:
Fichero 'datos.txt' cerrado con exito
Fichero 'salida.txt' cerrado con exito
Nota que al final imprime una línea vacía, ésto es porque el fichero está terminado en un return (un '\n'). Se podría eliminar ese defecto inspeccionando el contenido copiado al buffer. El valor de retorno de main() en caso de error es -1, que es más usual en lugar de 1.
==================
NOTAS. Una alternativa más breve a:
fichero = fopen( nombre, "r" );
if ( fichero == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre ); /* error */
return -1;
}
es:
if ( ( fichero = fopen( nombre, "r" ) ) == NULL ) {
printf( "Fichero '%s' no se pudo abrir.\n", nombre ); /* error */
return -1;
}