Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.82/34: Рейтинг темы: голосов - 34, средняя оценка - 4.82
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 104

Буфер слишком мал

25.10.2013, 21:19. Показов 7054. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравия желаю!
Начал учить MFC с помощью 1 сайта. Там приводится такой вот код для использования буфера обмена:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CMyClip::CopyText(CString test)
{
    if (AfxGetMainWnd()->OpenClipboard())// если буфер обмена удалось открыть то
    {
        if (EmptyClipboard())   // Очистить буфер
        {
            HGLOBAL clipbuffer;
            char * buffer;  // указатель на данные
            clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()+1);// выделить память
            buffer = (char*)GlobalLock(clipbuffer); // блокировать буфер
            strcpy(buffer, LPCSTR(test));   // копировать в него данные
            GlobalUnlock(clipbuffer);   // разблокировать
            SetClipboardData(CF_TEXT,clipbuffer);   // установить данные и тип
            if (!CloseClipboard()) AfxMessageBox("Error Close");// закрыть
        } else AfxMessageBox("Error Empty");
    } else AfxMessageBox("Error Open");
}
Так как этот код писался под VS 6.0 или 5.0, я его переделал под свой 2012 таким образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CMyClip::CopyText(CString test)
{
    if (AfxGetMainWnd()->OpenClipboard())// если буфер обмена удалось открыть то
    {
        if (EmptyClipboard())   // Очистить буфер
        {
            HGLOBAL clipbuffer;
            wchar_t * buffer;   // указатель на данные
            clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()+1);// выделить память
            buffer = (wchar_t*)GlobalLock(clipbuffer);  // блокировать буфер
            wcscpy_s(buffer, test.GetLength(), test);   // копировать в него данные
            GlobalUnlock(clipbuffer);   // разблокировать
            SetClipboardData(CF_TEXT,clipbuffer);   // установить данные и тип
            if (!CloseClipboard()) AfxMessageBox(L"Error Close");// закрыть
        } else AfxMessageBox(L"Error Empty");
    } else AfxMessageBox(L"Error Open");
}
Всё компилируется, но при выполнении этой функции, а точнее в её 11 строке, программа вылетает с сообщением

Debug Assertion Failed!
Program:................
File: f:\dd\vctools\crt_bld\self_x86\crt\src\t cscpy_s.inl
Line: 30

Expression: (L "Buffer is too small" && 0)

Я полазил по просторам великого и могучего (почти что русского языка), и напоролся на подобные проблемы, но не очень понял: а что же надо сделать с этим чертовым wcscpy_s. Так как подобный код вижу впервые, было бы неплохо, если информация будет чуть разжеванной. В рот положу её сам.

Добавлено через 15 минут
Подъем темы...

Добавлено через 14 минут
Подъем темы...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.10.2013, 21:19
Ответы с готовыми решениями:

Буфер обмена API слишком мал
Имеется схд на базе Synology Disk Station, сегодня перестал быть доступным с большей части рабочих мест, выдаёт следующую ошибку - Буфер...

Раздел /boot слишком мал для установки обновления
Уважаемые знатоки! Напоролся на странную фичу: Очередное обновление жалуется на недостаток места в разделе /boot. Раздел установлен...

Размер целевой строки слишком мал для представления экземпляра XML
select distinct *, STUFF(cast((select = ', ' + t1.category from category as ...

26
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
25.10.2013, 22:33
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
Спасибо
для спасибы кнопки есть
0
87 / 86 / 27
Регистрация: 04.10.2012
Сообщений: 355
25.10.2013, 22:34
Вообще, правила хорошего тона полагают написание универсального кода для ACSII и UNICODE:
C++
1
2
3
4
5
6
7
8
9
10
11
void CMyClip::CopyText(CString test) {
  if (AfxGetMainWnd()->OpenClipboard()) {
    if (EmptyClipboard()) {
      HGLOBAL clipbuffer = GlobalAlloc(GMEM_DDESHARE, (test.GetLength() + 1) * sizeof(TCHAR));
      TCHAR *buffer = (TCHAR *)GlobalLock(clipbuffer);
      _tcscpy_s(buffer, test.GetLength() * sizeof(TCHAR), test);
      GlobalUnlock(clipbuffer);
      SetClipboardData(CF_TEXT, clipbuffer);
      if (!CloseClipboard()) AfxMessageBox(TEXT("Error Close"));}
    else AfxMessageBox(TEXT("Error Empty"));}
  else AfxMessageBox(TEXT("Error Open"));}
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
25.10.2013, 22:35
Цитата Сообщение от mytilus Посмотреть сообщение
test.GetLength() * 2
по правильному вот так
test.GetLength() * sizeof(wchar_t)
а то вдруг там будет не 2х байтная кодировка
0
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 104
25.10.2013, 22:44  [ТС]
Попробовал с Юникодом так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CMyClip::CopyText(CString test)
{
    if (AfxGetMainWnd()->OpenClipboard())// если буфер обмена удалось открыть то
    {
        if (EmptyClipboard())   // Очистить буфер
        {
            HGLOBAL clipbuffer;
            wchar_t * buffer;   // указатель на данные
            clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()*2+2);// выделить память
            buffer = (wchar_t*)GlobalLock(clipbuffer);  // блокировать буфер
            wcscpy_s(buffer, test.GetLength()*2+2, test);   // копировать в него данные
            GlobalUnlock(clipbuffer);   // разблокировать
            SetClipboardData(CF_UNICODETEXT,clipbuffer);    // установить данные и тип
            if (!CloseClipboard()) AfxMessageBox(L"Error Close");// закрыть
        } else AfxMessageBox(L"Error Empty");
    } else AfxMessageBox(L"Error Open");
}
При отладке
C++
1
SetClipboardData(CF_UNICODETEXT,clipbuffer);    // установить данные и тип
выдает вызов точки останова.

Добавлено через 2 минуты
Сейчас посмотрю с вашими кодами

Добавлено через 1 минуту
С вашим кодом то же самое.

Добавлено через 40 секунд
"*.exe вызвал срабатывание точки останова."
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
25.10.2013, 23:02
Цитата Сообщение от mytilus Посмотреть сообщение
_tcscpy_s(buffer, test.GetLength() * sizeof(TCHAR), test);
ты здесь не учитываешь завершающий ноль
C++
1
_tcscpy_s(buffer, (test.GetLength() +1)* sizeof(TCHAR), test);
вот так получше будет
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
"*.exe вызвал срабатывание точки останова."
а ты эту статейку читал?
http://www.firststeps.ru/mfc/w... d/r.php?53
CF_UNICODETEXT - Только Windows NT: Формат текста Уникода. Каждая строка оканчивается комбинацией возврата каретки / перевода строки (CR-LF). Символ пробела сообщает о конце данных.
в конце должен быть пробел

Добавлено через 1 минуту
от туда же
Если параметр hMem идентифицирует объект в памяти, объект, должен быть помещен, используя функцию GlobalAlloc с флажками GMEM_DDESHARE и GMEM_MOVEABLE.
0
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 104
25.10.2013, 23:39  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
в конце должен быть пробел
То есть ручками добавить пробел в последние байт*sizeof(TCHAR)?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
26.10.2013, 16:18
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
wchar_t * buffer; * // указатель на данные
* * * * * * clipbuffer = GlobalAlloc(GMEM_DDESHARE, test.GetLength()*2+2);
- wchar_t подразумевает использование юникода. Опираясь на данную фразу
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
Начал учить MFC с помощью 1 сайта.
делаю вывод что о кодировке проекта врядли вообще думали прежде чем создать проект.
По маросу L делаю вЫвод в проекте тип кодировки юникод
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
AfxMessageBox(L"Error Close");
, а это значит что вот здесь *2 + 2 не требуется
Цитата Сообщение от TempuSFatumA Посмотреть сообщение
wcscpy_s(buffer, test.GetLength()*2+2, test);
, т.к этим пытаемся запихнуть строку в 2 раза большей длины(!).
wcscpy_s копирует многобайтные символы и 2-м параметром надо передать число символов а не число байтов.
wcscpy_s когда в него передавалась в 2-раза большее число символов как и положено ему генил исключение, которое никем не обрабатывалось и приводило к вылету программы.
C++
1
2
3
4
5
errno_t wcscpy_s(
   wchar_t *strDestination,
   size_t numberOfElements,
   const wchar_t *strSource 
);
Советую записать вот так memcpy(buffer, test.GetLength()*2, test); и не ломать голову.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.10.2013, 16:18

Из текста "Мал ребенок, да удал" получить "Удал ребенок, да мал"
Задали три задачки, однако совсем забыл эту тему. Прошу вашей помощи 1) Из текста "Мал ребенок, да удал" получить "Удал...

Диск С очень мал
Диск С находится в последнем разделе. Он объёмом 25 гигабайт. ОС крыхтит. Как быть? Из предыдущего раздела взять нельзя.

Мобильная видеокарта AMD - ценник сильно мал?
Samsung 300E5V (NP300E5V-S02RU), наткнулся на этот ноутбук, 450 долларов, кастрированный пентиум 997, нооо Графический адаптер:...

Требуется разработать информационную систему мал.предприятия
Требуется программист (можно со-товарищи) для разработки информационной системы мал.предприятия (строительство) на базе MS (SQL Server,...

Какая материнская плата и процессор подойдут, если бюджет крайне мал
Здравствуйте. Такой вопрос - отдали asus geforce gtx 1050 strix и Ballistix Sport LT Gray 8GB DDR4-2400 UDIMM в подарок. Хочется обновить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 16.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 04.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru