I just found something that I cant understand. I have a function that I want not only run in main(), but to use it in another function (for edit file) and I dont want to create an extra global variables.
int fileOut(bool = 1, char filename[] = 0);
//...
int fileOut(bool output, char filename[15]){
cin >> filename; // and if I do so, Ill got the error like this:
// Exception thrown: Write access violation. _Str was 0x1110112.
cout << filename;
return 0;
}
Soo, is theres a solution how to fix this and make possible change filename?
CodePudding user response:
In a function parameter, char filename[15]
is actually treated by the compiler as simply char *filename
, which you are defaulting to 0
, aka NULL
/nullptr
. So, if the caller doesn't provide a buffer for filename
, it won't point anywhere useful, so you can't write data to it, hence the crash.
In that situation, you can use a local variable to write to, eg:
int fileOut(bool output, char filename[15]){
char buffer[15] = {};
if (!filename) filename = buffer;
cin >> filename;
cout << filename;
return 0;
}
Just be careful of a buffer overflow, since the user could enter more than 15 characters! You can use cin.get()
to mitigate that:
cin.get(filename, 15);
Though, you really should be using std::string
instead of char[]
, eg:
int fileOut(bool = 1, std::string filename = "");
//...
int fileOut(bool output, std::string filename){
cin >> filename;
cout << filename;
return 0;
}
Either way, what is the point of letting the user pass in an input string if the function is just going to overwrite it? If the function always prompts the user, then just use a local variable instead of a parameter:
int fileOut(bool = 1);
//...
int fileOut(bool output){
char filename[15] = {};
cin.get(filename, 15);
cout << filename;
return 0;
}
Or:
int fileOut(bool = 1);
//...
int fileOut(bool output){
std::string filename;
cin >> filename;
cout << filename;
return 0;
}
Otherwise, if you want the caller to be able to provide a filename, and then prompt the user if no filename is given, try something more like this instead:
int fileOut(bool = 1, char filename[15] = 0);
//...
int fileOut(bool output, char filename[15]){
char buffer[15] = {};
if (!filename) filename = buffer;
if (*filename == 0)
cin.get(filename, 15);
cout << filename;
return 0;
}
Or:
int fileOut(bool = 1, std::string filename = "");
//...
int fileOut(bool output, std::string filename){
if (filename.empty())
cin >> filename;
cout << filename;
return 0;
}