Есть ли решение для переопределения аргумента в C ?

#c

#c

Вопрос:

Я только что нашел кое-что, чего не могу понять. У меня есть функция, которую я хочу не только запустить в main (), но и использовать ее в другой функции (для редактирования файла), и я не хочу создавать дополнительные глобальные переменные.

 int fileOut(bool = 1, char filename[] = 0);  //...  int fileOut(bool output, char filename[15]){  cin gt;gt; filename; // and if I do so, Ill got the error like this:  // Exception thrown: Write access violation. _Str was 0x1110112.   cout lt;lt; filename;  return 0; }  

Су, есть ли решение, как это исправить и сделать возможным изменение имени файла?

Комментарии:

1. используйте строковый объект

2. Какова цель fileOut() этого ?

3. cin gt;gt; filename создает хороший вектор атаки переполнения буфера.

4. @FredLarson я собираюсь прочитать файл и вывести результат в таблицу

5. @SaMartinell: fileOut() собираетесь ли вы все это делать?

Ответ №1:

В параметре функции char filename[15] компилятор фактически обрабатывает его как простой char *filename , который вы используете по умолчанию 0 , он же NULL / nullptr . Таким образом, если вызывающий абонент не предоставит буфер для filename , он не укажет ничего полезного, поэтому вы не сможете записать в него данные, отсюда и сбой.

В этой ситуации вы можете использовать локальную переменную для записи, например:

 int fileOut(bool output, char filename[15]){  char buffer[15] = {};  if (!filename) filename = buffer;   cin gt;gt; filename;  cout lt;lt; filename;  return 0; }  

Просто будьте осторожны с переполнением буфера, так как пользователь может ввести более 15 символов! Вы можете использовать cin.get() , чтобы смягчить это:

 cin.get(filename, 15);  

Хотя, вам действительно следует использовать std::string вместо char[] , например:

 int fileOut(bool = 1, std::string filename = "");  //...  int fileOut(bool output, std::string filename){  cin gt;gt; filename;  cout lt;lt; filename;  return 0; }  

В любом случае, какой смысл позволять пользователю передавать строку ввода, если функция просто собирается ее перезаписать? Если функция всегда запрашивает пользователя, то просто используйте локальную переменную вместо параметра:

 int fileOut(bool = 1);  //...  int fileOut(bool output){  char filename[15] = {};  cin.get(filename, 15);  cout lt;lt; filename;  return 0; }  

Или:

 int fileOut(bool = 1);  //...  int fileOut(bool output){  std::string filename;  cin gt;gt; filename;  cout lt;lt; filename;  return 0; }  

В противном случае, если вы хотите, чтобы вызывающий абонент мог указать имя файла, а затем запросить пользователя, если имя файла не указано, попробуйте вместо этого что-то более похожее:

 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 lt;lt; filename;  return 0; }  

Или:

 int fileOut(bool = 1, std::string filename = "");  //...  int fileOut(bool output, std::string filename){  if (filename.empty())  cin gt;gt; filename;   cout lt;lt; filename;  return 0; }