www.mikrocontroller.net

Forum: PC-Programmierung Windows: Buffer too small


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: LFX3 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Guten Tag,

ich habe aus dem Buch "C - Einführung und professionelle Anwendung" 
folgendes Beispiel in Visual C++ 2008 Express eingegeben:

#include <stdio.h>
#include <windows.h>

HINSTANCE hInst = 0;
char szAppName[] = "Basis";
char szTitle[100] = "Willys Titelleiste";

BOOL InitApplication ();
BOOL InitInstance (int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

void onPaint (HWND);

int WINAPI WinMain (  HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR    lpCmdLine,
            int       nCmdShow)
{

  MSG msg;
  hInst = hInstance;

  if (!InitApplication () ) return FALSE;
  if (!InitInstance (nCmdShow) ) return FALSE;

  while (GetMessage (&msg, NULL, 0, 0))
  {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
  }



  return (msg.wParam);
}

BOOL InitApplication ()
{
  WNDCLASSEX wc;

  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInst;
  wc.hIcon = LoadIcon ( NULL, IDI_QUESTION);
  wc.hCursor = LoadCursor ( NULL, IDC_WAIT);
  wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = szAppName;
  wc.hIconSm = LoadIcon (NULL, IDI_WINLOGO);

  return RegisterClassEx(&wc);
}


BOOL InitInstance (int nCmdShow)
{
  HWND hWnd;
  hWnd = CreateWindow(
      szAppName,
      szTitle,
      WS_OVERLAPPEDWINDOW,
      50,//CW_USEDEFAULT,
      100,
      500,
      250,
      NULL,
      NULL,
      hInst,
      NULL);
  if (!hWnd) return (FALSE);
  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

  return (TRUE);
}


LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  
  switch (message)
  {
  case WM_PAINT:
    onPaint(hWnd);
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    return DefWindowProc (hWnd, message, wParam, lParam);
  }

  return 0;
}



void onPaint (HWND hWnd)
{
  PAINTSTRUCT ps;
  HDC hdc;
  TEXTMETRIC tm;
  char szZahl[10];

  int i = 0;
  int nXStart1, nXStart2, nYStart;
  int nAveCharWidth, nLineHeight;

  char* strMetrik[] = {  "Zeichenhoehe: ",
              "Hoehe oberhalb der Basislinie:",
              "Hoehe unterhalb der Basislinie:",
              "Hoehe des Bereichs fuer Umlaute:",
              "Abstand zwischen den Zeilen:",
              "Mittlere Zeichenbreite:",
              "Maximale Zeichenbreite:"
            };

  hdc = BeginPaint (hWnd, &ps);

  GetTextMetrics(hdc, &tm);
  nLineHeight = (int)(tm.tmHeight + tm.tmExternalLeading)+2;
  nAveCharWidth = (int)tm.tmAveCharWidth;

  nXStart1 = 5*nAveCharWidth;
  nXStart2 = nXStart1 + 40*nAveCharWidth;

  nYStart = 1*nLineHeight;

  for (i=0; i < 7; i++)
  {
    TextOut (hdc, nXStart1, nYStart, strMetrik[i], strlen(strMetrik[i]) );

    switch(i)
    {
    case 0: sprintf_s(szZahl, "%31d", tm.tmHeight);
        break;
    case 1: sprintf_s(szZahl, "%31d", tm.tmAscent);
        break;
    case 2: sprintf_s(szZahl, "%31d", tm.tmDescent);
        break;
    case 3: sprintf_s(szZahl, "%31d", tm.tmInternalLeading);
        break;
    case 4: sprintf_s(szZahl, "%31d", tm.tmExternalLeading);
        break;
    case 5: sprintf_s(szZahl, "%31d", tm.tmAveCharWidth);
        break;
    case 6: sprintf_s(szZahl, "%31d", tm.tmMaxCharWidth);
        break;
    };

    TextOut(hdc, nXStart2, nYStart, szZahl, strlen(szZahl) );
    nYStart += nLineHeight;

  }

  EndPaint (hWnd, &ps);
}



Ich erhalte folgende Fehlermeldung:

Debug Assertion Failed!
Program
...ges\textmetric\Debug\textmetric.exe
File f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c
Line 244
Expression:("Buffer too small", 0)



Kann mir jemand sagen, woran das liegt?


LFX3

Autor: Karl Heinz Buchegger (kbuchegg) (Moderator)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
>  char szZahl[10];

>    case 0: sprintf_s(szZahl, "%31d", tm.tmHeight);


Wie soll denn eine Zahl, die du mit 31 Dezimalstellen als Text 
dargestellt haben willst (und der Text daher aus 31 Zeichen bestehen 
wird), in einen String passen, der gerade mal Platz für 9 Zeichen hat?

Autor: Peter II (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
irgendwie stimmen die parameter nicht mit der doku überein

sprintf_s(szZahl, "%31d", tm.tmHeight);

http://msdn.microsoft.com/de-de/library/ce3zzk1k%2...

int sprintf_s(
   char *buffer,
   size_t sizeOfBuffer,
   const char *format [,
      argument] ...
);

Autor: LFX3 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Aua, danke für den Hinweis:


Statt
case 0: sprintf_s(szZahl, "%31d", tm.tmHeight);


muss es heißen:
case 0: sprintf_s(szZahl, "%3ld", tm.tmHeight);


VIELEN DANK
LFX3

Autor: Karl Heinz Buchegger (kbuchegg) (Moderator)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
LFX3 schrieb:

>
> case 0: sprintf_s(szZahl, "%3ld", tm.tmHeight);
> 

Es muss vor allen Dingen
sprintf_s( szZahl, sizeof(szZahl), "%3ld", tm.tmHeight);
heissen.
Auch wenn Microsoft mittels Template ...
template <size_t size>
int sprintf_s(
   char (&buffer)[size],
   const char *format [,
      argument] ... 
); // C++ only
... eine Automatik eingebaut hat, die dann greift, wenn der Compiler das 
Array selber sehen kann. Denn irgendwann hast du dann diesen Fall nicht 
mehr und dann ist das Kopfkratzen groß, was denn das Problem ist. Nichts 
gegen Komfort, aber zuviel Komfort macht nachlässig.

Und ob die "ld" richtig sind, muss man in der TEXTMETRIC Struktur 
nachsehen. Das steht
typedef struct tagTEXTMETRIC {  /* tm */
    int  tmHeight;
    int  tmAscent;
    int  tmDescent;
    int  tmInternalLeading;
    int  tmExternalLeading;
    int  tmAveCharWidth;
    int  tmMaxCharWidth;
    int  tmWeight;
    BYTE tmItalic;
    BYTE tmUnderlined;
    BYTE tmStruckOut;
    BYTE tmFirstChar;
    BYTE tmLastChar;
    BYTE tmDefaultChar;
    BYTE tmBreakChar;
    BYTE tmPitchAndFamily;
    BYTE tmCharSet;
    int  tmOverhang;
    int  tmDigitizedAspectX;
    int  tmDigitizedAspectY;
} TEXTMETRIC;

Nö. ld ist definitiv falsch. tmHeight ist vom Datentyp int. Also muss 
der Formatspecifier ein "d" sein und kein "ld".


Leg das Buch zur Seite und kauf dir erst mal ein vernünftiges 
Einsteigerbuch für C. Der Klassiker "Kernighan&Ritchie" wird immer 
wieder gerne genommen.
Wenn du den durch hast und auch verstehst, dann fallen dir die Fehler in 
diesem Buch dann auch auf. Alleine der Titel muss schon stutzig machen. 
Zwischen "Einführung" und "professioneller Anwendung" liegen im 
günstigen Fall so ca. 3 bis 4 Jahre und eine halbes Bücherregal an 
Literatur.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net