2009-04-16 15 views
8

Bien, aquí está el trato, estoy tomando una introducción a la clase de C++ en mi universidad y estoy teniendo problemas para averiguar cómo cambiar la extensión de un archivo. Primero, lo que se supone que debemos hacer es leer en un archivo .txt y contar palabras, oraciones, vocales, etc. Bien, lo tengo, pero el siguiente paso es lo que me preocupa. Entonces se supone que debemos crear un nuevo archivo usando el mismo nombre de archivo que el archivo de entrada, pero con la extensión .code en lugar de .txt (en ese nuevo archivo, codificaremos la cadena agregando números aleatorios al código ASCII de cada uno). personaje si estabas interesado). Siendo un principiante en la programación, no estoy muy seguro de cómo hacer esto. Estoy usando el siguiente fragmento de código para conseguir en un primer momento el archivo de entrada:¿Cómo se cambia la extensión de nombre de archivo almacenada en una cadena en C++?

cout << "Enter filename: "; 
cin >> filename; 
infile.open(filename.c_str()); 

Asumo para crear un nuevo archivo que voy a estar usando algo como:

outfile.open("test.code"); 

Pero no sabré cuál es el nombre del archivo hasta que el usuario lo ingrese, así que no puedo decir "test.txt". Entonces, si alguien sabe cómo cambiar esa extensión cuando creo un nuevo archivo, ¡lo agradecería mucho!

Respuesta

8

Hay varios enfoques para esto.

Puede adoptar el enfoque super perezoso y hacer que ingresen solo el nombre del archivo y no la extensión .txt. En ese caso, puede agregarle .txt para abrir el archivo de entrada.

infile.open(filename + ".txt"); 

A continuación, sólo llaman

outfile.open(filename + ".code"); 

El siguiente enfoque habría que tomar todo el nombre del archivo incluyendo la extensión, y simplemente añadir .code a ella por lo que tendría test.txt.code.

Es un poco ambiguo si esto es aceptable o no.

Por último, puede utilizar métodos std::stringfindreplace, y para obtener el nombre del archivo sin extensión, y usar eso.

+0

Muy bien, creo que las opciones están más en línea con lo que estaba buscando, ya que recientemente aprendimos sobre métodos de cadenas. ¡Gracias por el aporte! –

+2

Mejor rfind() ya que encontrará el último "." en lugar del primero en el caso de que 'a.b.c.txt' sea un nombre de archivo válido –

+1

.open() toma un const char *, no un std :: sting desafortunadamente. – MSalters

3

Aquí hay algunos consejos. Usted tiene un nombre de archivo que ya entró en - lo que quiere hacer es la parte del nombre de archivo que no incluye la extensión:

std::string basename(const std::string &filename) 
{ 
    // fill this bit in 
} 

Después de haber escrito esa función, se puede usar para crear el nombre de la nueva archivo:

std::string codeFile = basename(filename) + ".code"; 
outFile.open(codeFile); 
+0

No se olvide de probar. Me gusta nombrar mis archivos. Como.este – veefu

0

Pseudo código sería hacer algo como

outFilename = filename; 
<change outFilename> 
outfile.open(outFilename); 

para cambiar outFilename, mira strrchr y strcpy como punto de partida (podría ser métodos más apropiados - Eso funcionaría muy bien con un * char *)

+0

¿Por qué sugerir métodos de estilo C cuando el código es C++? –

4

No se lo regalar, ya que aprender es el objetivo del ejercicio, pero aquí hay una pista. Probablemente querrá una combinación de find_last_of y replace.

-1

Lo que tendrá que hacer es copiar el nombre de archivo original en una nueva variable donde puede cambiar la extensión.Algo como esto:

string outFilename; 
size_t extPos = filename.rfind('.'); 
if (extPos != string::npos) 
{ 
    // Copy everything up to (but not including) the '.' 
    outFilename.assign(filename, 0, extPos); 
    // Add the new extension. 
    outFilename.append(".code"); 
    // outFilename now has the filename with the .code extension. 
} 

Es posible que usted podría utilizar el "nombre de archivo" variable si no es necesario para mantener el nombre de archivo original alrededor para su uso posterior. En ese caso es posible que utilices:

size_t extPos = filename.rfind('.'); 
if (extPos != string::npos) 
{ 
    // Erase the current extension. 
    filename.erase(extPos); 
    // Add the new extension. 
    filename.append(".code"); 
} 

La clave es mirar a la definición de la clase string de C++ y entender lo que hace cada función miembro. El uso de rfind buscará hacia atrás a través de la cadena y no golpeará accidentalmente ninguna extensión en nombres de carpeta que puedan ser parte del nombre del archivo original (por ejemplo, "C: \ MyStuff.School \ MyFile.txt"). Cuando trabaje con los desplazamientos de find, rfind, etc., también deberá tener cuidado de usarlos correctamente al pasarlos como conteos a otros métodos (p. Ej., Use assign (filename, 0, extPos-1), asigne (filename, 0, extPos), assign (filename, 0, extPos + 1)).

Espero que ayude.

+3

Dado que es una pregunta de tarea, no des a conocer todo –

8

Por supuesto, si esto no fuera tarea sino un proyecto del mundo real, probablemente usted mismo, así como otras personas que lean su código, hagan un favor al usar Boost.Filesystem's replace_extension() en lugar de enrollar el suyo propio . Simplemente no hay funcionalidad que sea lo suficientemente simple como para que no se pueda encontrar un error, al menos en algún caso de esquina.

0

¿por qué no utilizar el método de cadena find_last_of()?

std::string new_filename = filename; 
size_type result = new_filename.find_last_of('.'); 

// Does new_filename.erase(std::string::npos) working here in place of this following test? 
if (std::string::npos != result) 
    new_filename.erase(result); 

// append extension: 
filename.append(".code"); 
0

En Windows (por lo menos) se puede utilizar para diseccionar _splitpath el nombre base del resto de las piezas, y luego volver a montar la utilización de su formateador cadena favorita.

0

Cómo sobre el uso strstr:

char* lastSlash; 
char* newExtension = ".code"; 
ChangeFileExtension(char* filename) { 
    lastSlash = strstr(filename, "."); 
    strcpy(lastSlash, newExtension); 
} 
0

me gustaría simplemente añadir ".code" al nombre de archivo que el usuario introduce. Si ingresaban "test.txt", el archivo de salida sería "test.txt.code". Si ingresaron un nombre de archivo sin extensión, como "prueba", el archivo de salida sería "test.code".

Utilizo esta técnica todo el tiempo con programas que generan archivos de salida y algún tipo de salida de registro/diagnóstico relacionada. Es simple de implementar y, en mi opinión, hace que las relaciones entre los archivos sean mucho más explícitas.

5

de vez en cuando hago esta pregunta y terminan en esta página, por lo que para futuras referencias, aquí es la sintaxis de una sola línea:

string newfilename=filename.substr(0,filename.find_last_of('.'))+".code"; 
+0

No funciona con algo como "file.tar.gz" –

+0

Funciona si la definición de "extensión" es "lo que sea después del último punto", que es razonable si estamos buscando una regla empírica simple. Para casos especiales como archivos descomprimidos, nombres de archivos con números de versión, Makefiles, etc., uno solo debe definir una política especial e implementarla en un método dedicado. – Narcolessico

0
size_t pos = filename.rfind('.'); 
if(pos != string::npos) 
    filename.replace(pos, filename.length() - pos, ".code"); 
else 
    filename.append(".code"); 
+0

Por favor, actualice su respuesta con explicación. –

+0

Aunque este código puede responder a la pregunta, proporcionando contexto adicional con respecto a _why_ y/o _how_ responde la pregunta mejoraría significativamente su valor a largo plazo . Por favor [edite] su respuesta para agregar alguna explicación. –

+0

std :: string :: replace puede tomar string :: npos como len (en lugar de calcular length - pos), que reemplazará hasta el final de la cadena. – user79878

Cuestiones relacionadas