Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hallo Forum,

ich verwende einen CString um Textinhalte zusammen zu setzen. Leider bekomme ich nciht den kompletten Text in eine Variable von CString rein, daher stellt sich meine Frage, ob es eine andere Möglichkeit gibt einen String zu speichern.

Beste Grüße

Patrick

  • Autor

Also, ich wüsste jetzt nicht wo mein Fehler liegen könnten, aber nachfolgend findest Du den Code:


CString strMSSQLStatement;

strMSSQLStatement.Format(_T("SET ANSI_WARNINGS OFF; ")

_T(" INSERT INTO [%s_%s] ")

_T(" ( ")

_T(" IdAddress, IdUserCreate, TimeCreate, OP_SeminarVon, OP_SeminarBis, OP_Seminarname, ")

_T(" OP_Bestellnummer, OP_Verpflegung, OP_LaufendeNummer, OP_AngenommenVon, OP_AngenommenVonName ")

_T(" ) ")

_T(" VALUES ")

_T(" (%d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s'); ")

_T(" SET ANSI_WARNINGS ON; ")

, CString(GetVIPSQLTableName(VIPTBL_KUNDEN, 1))

, CString(GetVIPSQLTableName(VIPTBL_EX_KUNDEN_SEMINARBEWEGUNG, 2))

, lAddressId

, 1

, szDate

, dlg.m_strSeminarFrom.GetString()

, dlg.m_strSeminarTo.GetString()

, dlg.m_strSeminarName.GetString()

, dlg.m_strSeminarName.GetString()

, atol(dlg.m_strSeminarVerpflegung.GetString())

, dlg.m_lSerialNumber

, lUserId

, strUserName.GetString());

Vielleicht siehst Du ja den Fehler ;-(

Wird der String ab einer bestimmten Länge abgeschnitten, oder ab einem bestimmten Feld?

Der Fehler muss übrigens nicht dort stecken, wo er sich bemerkbar macht. Es kann sein, dass du schon vorher den Speicher der Strings durcheinanderbringst, z.B. durch einen Aufruf von GetBuffer ohne nachfolgenden Aufruf von ReleaseBuffer.

Der String wird nach einer bestimmte Länge abgeschnitten, das habe ich schon getestet.
Wie stellst du die Länge fest? Und welche Länge ist das?

Der Aufruf ist wie Du ihn sieht, ich rufe keine anderen Funktionen vorweg auf.

Du meinst, du benutzt vorher im gesamten Programm keine Methoden von CString? Das glaube ich nicht ;)

ICh verwende zwar CString, aber genau so, wie Du ihn sieht.
Du benutzt also nur CString::Format? Nirgendwo GetBuffer oder LockBuffer oder ein Cast auf einen nicht-const-Zeiger?

Kannst du ein Minimalbeispiel erstellen, das den Fehler reproduziert?

Wie kann ich den Buffer erhöhen? Was müsste ich machen?
Gar nichts, das muss von ganz allein funktionieren. Wenn nicht, hast du mit an Sicherheit grenzender Wahrscheinlichkeit einen Fehler in deinem Code.

Und nochmal die Frage: Wie stellst du die Länge fest, und bei welcher Länge wird abgeschnitten?

Kann es sein, dass der Fehler darin besteht, dass ich %s mit einem CString fülle?
Nicht, solange du das nur mit CString::Format machst (und nicht etwa mit sprintf).

Allerdings darfst du das CString-Objekt, dessen Format-Methode du aufrufst, nicht als Parameter im selben Aufruf benutzen.

Möchtest du eigentlich meine Fragen nicht beantworten?

  • Autor

Oh sorry, die Länge habe ich gestest indem ich einen kürzeren und längeren Text eingelesen habe, es wurde immer nur die gleiche Anzahl an Zeichen dargestellt.

Ich rufe folgende Befehle aus:

FORMAT

GETSTRING

ALLOCSYSSTRING

Weitere Befehler rufe ich nciht aus, ein Beispiel kann ich leider auf die schnelle nciht fertig machen und die Codes darf ich nciht rausgeben, sorry.

Oh sorry, die Länge habe ich gestest indem ich einen kürzeren und längeren Text eingelesen habe, es wurde immer nur die gleiche Anzahl an Zeichen dargestellt.
Wo wurde denn dargestellt? Ich will nur sicherstellen, dass es nicht die Darstellung ist, die eine Begrenzung hat. Hast du dir die Länge mit GetLength ausgeben lassen?

Und welche Länge ist es nun?

  • Autor

Ich habe mir die Länge jetzt direkt mit GETLENGHT zurück geben lassen und habe ein sehr interessantes Ergebnis. Je nachdem wieviele Zeichen ich am Anfang ergänze oder kürze verändert sich die Länge.

Einmal 462 dann 506 dann 536.

Es muss was mit der Formatierung zu tun haben, oder sehe ich das Falsch?

Selbstverständlich ist mir das in den Sinn gekommen
Ja und warum sagst du dann nicht endlich mal, welches Feld das ist?

Warum muss ich dir jedes Fitzelchen Information aus der Nase ziehen? Warum muss ich meine Fragen andauernd wiederholen? Allmählich verliere ich die Lust, dir zu helfen.

  • Autor

Also, ich übergabe nur LONG und CString Felder.

Ich habe noch einmal getestet ab wann genau abgeschnitten wird, leider variaert das noch wenn in den CSTRINGS längere und kürzere Texte vorhanden sind, daher ist es nicht möglich zu sagen, bei welchen Feld abgeschnitten wird. Es scheint aber an folgenden zu liegen:


, dlg.m_strSeminarName.GetString()

, atol(dlg.m_strSeminarVerpflegung.GetString())

, dlg.m_strSeminarName.GetString() 

, lUserId

, strUserName.GetString()

Es wurde mir gesagt, es könnt daran liegen, dass ich CSTRING in einen CSTRING eintragen möchte. Leider finde ich nicht im Internet was diese theorie bestätigen könnte.

Es wurde mir gesagt, es könnt daran liegen, dass ich CSTRING in einen CSTRING eintragen möchte. Leider finde ich nicht im Internet was diese theorie bestätigen könnte.

Das ist auch Unsinn. Das funktioniert, sowohl mit GetString als auch ohne.

Wie sieht denn GetVIPSQLTableName aus?

  • Autor

Habe ich mir mittlerweile auch gedacht, ich da in dem Programm bereits ca. 40 SQL-Statements genau so aufgebaut werden. Diese sind nur alle relativ kurz, daher gabes bisher keine Probleme.

Hier findest Du die komplette Funktion:


BSTR CKMPokoVIPSQLAddInCtrl::GetVIPSQLTableName(LPCTSTR bstrTableName, INT iTableType)

{

	CLSDatabase Database;

	CTable Table;


	CString strName, strTable, strTabelName, strSQLQuery;


	switch(iTableType)

	{

	case 1:

		strName		= "tblAS0000";

		strTable	= "tblMasterAddrSets";

		break;


	case 2:

		strName		= "EX0000";

		strTable	= "tblMasterRelations";

		break;


	case 3:

		strName		= "PJ0000";

		strTable	= "tblMasterProjects";

		break;

	}


	if (Database.Open(&m_strMSSQLUser, &m_strMSSQLPassword, &m_strMSSQLConnectionString))

	{

		CString strMSSQLStatement;

		strMSSQLStatement.Format(_T("SELECT [T1].[Id]")

								 _T("FROM [%s] AS [T1] ")

								 _T("WHERE [Name]='%s' ")

								 , strTable.GetString()

								 , bstrTableName);


		if (Database.Execute(&strMSSQLStatement, Table))

		{

			if (Table.ISEOF() == false)

			{

				Table.MoveFirst();


				strTabelName = Table.Get("Id");

				strTabelName = strName.Left(strName.GetLength() - strTabelName.GetLength()) + strTabelName;

			}

		}

	}


	return strTabelName.AllocSysString();

}

Hintergrund der Funktion ist, die Datenbank die angesteuert wird, ist durch Mastertabellen komplett dynamisch. Der Benutzer kann die internen Tabellennamen nciht kennen. Die Funktion liesst die internen Namen aus. Dadurch können die Codes auch auf andere Systeme portiert werden.

Warum ist der Rückgabetyp BSTR?

Ist dir klar, dass du mit AllocSysString ein Speicherleck hast? Rohe BSTRs erfordern explizites Speichermanagement.

"LPCTSTR bstrTableName" ist auch nicht so toll. Wenn du schon UN benutzt, sollten die Namen auch zu den Typen konsistent sein.

Wirfst du auch noch an anderer Stelle im Code so mit BSTRs um dich? Das könnte deine Heapprobleme erklären.

  • Autor

Stimmt, war keine gute Idee. Hahe die Rückgabe auf CString geändert. Leidergab es keine Abhilfe für das Problem, der String wird immer noch abgeschnitten.

Ansonsten sind die Konventionen eingehalten. Kein BSTR als Rückgabe.

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.