БлогNot. C++: strcpy и "нарушение прав доступа при записи"

C++: strcpy и "нарушение прав доступа при записи"

UPD, коротко. В современных версиях Studio не забывайте указывать модификатор const для char *, ибо неконстантные указатели теперь вне закона:

const char *s = "Hello";

Если Вы, как и многие, обучались программировать на древней Сишной консоли, то Вам, как и мне, естественным кажется код вроде

char *s = "строка"; 

В хорошем учебнике, конечно, всегда оговорено, что это не копирование строки, а просто установка указателя на некоторую область памяти - фактический массив символов. Проблема в том, что в новых средах, например, в той же Visual Studio, "права" указателей сильно урезаны, так что область "строка", скорее всего, будет только read only, и писать в неё новые данные - потенциально опасное занятие.

Так, указанный выше подход приведёт к Runtime-ошибке нарушения прав доступа при использовании функции strcpy для копирования в строку s нового значения:

strcpy (s,"новая");

Кстати, "естественное"

char s[6]; strcpy (s,"строка");

тоже ошибочно - функция strcpy скопирует строку вместе с нуль-терминатором, так что для строки из N байт нужен буфер размерностью N+1 байт (конечно, если строки у нас - однобайтовые). Верным решением будет

char s[7]; strcpy (s,"строка");

Пример более-менее корректной программы на Studio с использованием char * и strcpy:

Вывести на экран показания часов.
Исходные данные – часы и минуты в формате целых чисел. Результат должен быть представлен в смешанной текстово-числовой форме с учетом падежных окончаний, например:
2 48 – 2 часа 48 минут ночи,
5 00 – 5 часов утра ровно,
12 00 – полдень,
12 23 – 12 часов 23 минуты дня,
13 12 – 1 час 13 минут дня,
21 33 – 9 часов 33 минуты вечера,
00 00 – полночь,
03 01 – 3 часа 1 минута ночи.
Использовать следующие границы частей суток:
5 час. <= утро < 12 час.,
12 < день < 18 час.,
18 <= вечер <= 23 час.,
0 час. < ночь < 5 час.
В случае ввода невозможных показаний часов выдать соответствующее сообщение, например:
24 03 – введены недопустимые данные.

Консольное приложение Visual C++ для решения задачи:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
 
char *goodwordform(int k,char *w,char *o1,char *o2,char *o5) {
 char *r = new char [strlen(w)+max(strlen(o1),max(strlen(o2),strlen(o5)))+1];
 strcpy (r,w);
 if ( (k%100>10 && k%100<20) || k%10>4 || k%10==0) r=strcat(r,o5);
 else if (k%10==1) r=strcat(r,o1);
 else r=strcat(r,o2);
 return r;
} 
 
int main () {
  setlocale(LC_ALL, "rus");
  int h,m;
  int timetags[4] = { 4, 11, 17, 23 };
  char *timemessages[4] = { "ночи" ,"утра","дня","вечера"};
  cout << "Введите часы и минуты: ";
  cin >> h >> m;
  if (h<0 || h>23 || m<0 || m>59) {
    cout << "Недопустимое время!";
    cin.sync(); cin.get(); return 1;
  }
  int index=0;
  while (h>timetags[index]) index++;
  if (h>12) h%=12;
  if (m==0) {
   if (h==0) cout << "полночь";
   else if (h==12) cout << "полдень";
   else cout << h << " " << goodwordform(h,"час","","а","ов") << " " <<
    timemessages[index] << " " << "ровно";
  }
  else cout << h << " " << goodwordform(h,"час","","а","ов") << " " << 
    m << " " << goodwordform(m,"минут","а","ы","") << " " << timemessages[index];
  cin.sync(); cin.get();
  return 0;
}

11.09.2014, 14:07 [12186 просмотров]


теги: c++ программирование ошибка алгоритм время studio

К этой статье пока нет комментариев, Ваш будет первым