Pregunta

Está bien éste es el trato, estoy tomando una introducción a la clase C ++ en mi universidad y estoy teniendo problemas para encontrar la manera de cambiar la extensión de un archivo. En primer lugar, lo que se supone que debemos hacer es leer en un archivo .txt y contar palabras, oraciones vocales, etc. Bueno, tengo esto, pero el siguiente paso es lo que me está molestando. A continuación, se supone que debemos crear un nuevo archivo con el mismo nombre de archivo que el archivo de entrada, pero con la extensión .code en lugar de .txt (en ese nuevo archivo estamos entonces para codificar la cadena mediante la adición de números aleatorios para el código ASCII de cada personaje si estaban interesados). Al ser un principiante en la programación, no estoy muy seguro de cómo hacer esto. Estoy usando el siguiente fragmento de código para entrar en un primer momento el archivo de entrada:

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

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

outfile.open("test.code");

Pero no voy a saber cuál es el nombre del archivo es hasta que el usuario entra en ella por lo que no puede decir "test.txt". Así que si alguien sabe cómo cambiar extenstion que cuando se crea un nuevo archivo Me gustaría mucho agradecerán!

¿Fue útil?

Solución

Hay varios enfoques para esto.

Puede tomar el enfoque muy perezoso, y hacer que entren en el nombre del fichero, y no la extensión .txt. En cuyo caso puede anexar .txt a él para abrir el archivo de entrada.

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

A continuación, que acaba de llamar

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

El siguiente enfoque sería 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 ambigua si esto es aceptable o no.

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

Otros consejos

Yo 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";

Por supuesto, si esto no fuera tarea, pero un proyecto en el mundo real, es probable que haría usted mismo - al igual que otras personas la lectura de su código - un favor mediante el uso de Boost.Filesystem 's replace_extension() en vez de rodar su propio. Simplemente no hay una funcionalidad que es bastante simple que no se podía llegar a un fallo, al menos en algunos casos esquina.

No hay que dar a la basura ya que el aprendizaje es el punto central del ejercicio, pero aquí va una pista. Lo que probablemente va a querer una combinación de find_last_of y replace .

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 del nuevo archivo:

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

Pseudo código sería hacer algo como

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

Para cambiar outFilename, un vistazo a strrchr y strcpy como punto de partida (puede haber métodos más apropiados - que sería un gran trabajo con un char * sin embargo)

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

¿Por qué no se utiliza 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");

Me acaba de añadir ".code" al nombre de archivo que el usuario introduce. Si entraban "test.txt", entonces el archivo de salida sería "test.txt.code". Si entraban en un nombre de archivo sin extensión, como "prueba", entonces el archivo de salida sería "test.code".

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

¿Y si uso strstr:

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

Lo que usted necesita hacer es copiar el nombre de archivo original en una nueva variable que permite 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. Usando rfind va a buscar hacia atrás a través de la cadena y no se golpeó accidentalmente todas las extensiones en los nombres de carpetas que pueden ser parte del nombre de archivo original (por ejemplo, "C: \ MyStuff.School \ MyFile.txt"). Cuando se trabaja con las compensaciones de hallazgo, rfind, etc., también querrá tener cuidado de usar de manera adecuada al pasar a ellos como cuentas a otros métodos (por ejemplo, qué utiliza asignar (nombre de fichero, 0, EXTPOS-1), asignar (nombre de archivo, 0, EXTPOS), asignar (nombre de archivo, 0, EXTPOS + 1)).

Espero que ayude.

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

Muy fácil:

string str = "file.ext";

str[str.size()-3]='a';
str[str.size()-2]='b';
str[str.size()-1]='c';

cout<<str;

Resultado: "File.abc"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top