#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
int main() {
char filename[200]; // no need to be stingy
std::ifstream file;
while (true) {
std::cout << "Filename: ";
// fgets is the proper way to read a line of text (possibly
// containing spaces) into a C-style char array without the
// possibility of overflowing it. If the user enters the EOF
// char from the terminal (Ctrl-Z in Windows, Ctrl-D otherwise)
// then we quit.
if (!std::fgets(filename, sizeof filename - 4, stdin)) {
std::cout << "Quitting\n";
return 0;
}
// But fgets leaves the newline at the end of the string
// so we need to remove it.
char *p = std::strchr(filename, '\n');
if (p) *p = '\0';
// strcat concatenates a c-style string onto another c-style string.
// We left at least 4 chars in the array to have room for ".txt"
std::strcat(filename, ".txt");
file.open(filename);
if (file) break;
std::cerr << "Can't open " << filename << '\n';
}
std::cout << "Opened " << filename << '\n';
//...
}
But in C++ we have the good fortune of having the std::string class, so we can do it like this:
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string filename;
std::ifstream file;
while (true) {
std::cout << "Filename: ";
// getline is the proper way to read a line of text (possibly
// containing spaces) into a C++ style string. The string will
// automatically grow to the required size. If the user enters
// the EOF char from the terminal, we quit.
if (!getline(std::cin, filename)) {
std::cout << "\nQuitting\n";
return 0;
}
// We can use the overloaded += operator to concatenate to
// a C++ string.
filename += ".txt";
file.open(filename);
if (file) break; // if no errors, then the file was found and opened.
std::cerr << "Can't open " << filename << '\n';
}
std::cout << "Opened " << filename << '\n';
//...
}
the trouble with this is that about 50% or more of all text files do not end in txt :) I have .dat, .sql, .cpp, .c, .asm, and about 200 other text file extensions. I just associate the extension with the editor I want so double click works, but I would't want notepad++ taking x.cpp and changing that to x.cpp.txt then telling me it did not exist.
so for the original C version, at the very least I would do something like
char *cp;
cp = strstr(filename, "."); //c++ string uses find() for this idea
if(cp)
///open filename
else
//open filename + .txt added.
even that is an issue if you have extensionless text files, but its one idea.
another idea would be to attempt to open filename, and if that fails, *then* try to open filename with .txt added. Every solution will fail for some scenario because you are fixing a non-issue with an assumption, though, so be aware of that.
You may want to know the C version just in case you use argv as the filename. You can stuff that into a c++ string, but there comes a point when avoiding a line or two of C just to avoid a line or two of C is kinda silly.