C – Logdatei schreiben

#include <stdio.h>
#include <stdlib.h>

/* Textfile zum Schreiben und Anfügen öffnen */
FILE *f = fopen("c:\\logfile.log", "a+t");

if (f != NULL)
{
    float fValue = 0.1;

    /* eine Zeile in die Datei schreiben */
    /* siehe auch: http://www.cplusplus.com/reference/clibrary/cstdio/fprintf/ */
    fprintf(f, "value:%f\n", fValue);

    /* Datei schließen */
    fclose(f);
}

Verwendung von _TCHAR, wchar_t (Unicode)

Ein schöner Artikel zum Thema befindet sich hier: Link

Zu beachten: Unicode/Multibyte-Einstellung unter Projekt->Eigenschaften->Konfigurationseigenschaften->Allgemein->Zeichensatz

#include <tchar.h> // meist in stdafx.h

// Anwendung, wobei die Makros _T und _TEXT identisch sind
wchar_t wcText[] = _T("Unicode-Text");

oder

wchar_t wcText[] = _TEXT("Unicode-Text");

Richtiger Vergleich von floating-point-Werten

#include <math.h> // für fabs()

float f1 = 0.11111111111;
float f2 = 0.1111111111;

// um Rundungsfehler zu umgehen sollte man mit einer
// Epsilon-Schranke (minimaler Abstand) arbeiten
// im Beispiel beträgt diese Schranke 1E-5
if (fabs(f1 - f2) < 1E-5)
{
    // f1 gleich f2
}

// verbesserte Version:
if (fabs(f1 - f2) < 1E-5 * f1)
{
    // f1 gleich f2
}

C – Datenwerte (float) aus einer Textdatei lesen und umwandeln

#include <stdio.h>
#include <stdlib.h>

/* Textfile zum Lesen öffnen */
FILE *f = fopen("myfile.txt", "rt");

if (f != NULL)
{
    /* Puffer mit 20 Zeichen */
    char buf[20];

    /* 25 Zeilen lesen */
    for (int d = 0; d < 25; d++)
    {
        /* eine Zeile mit max. 20 Zeichen aus dem File in den Puffer einlesen */
        if (fgets(buf, 20, f) != NULL)
        {
            /* Zeichenkette in float wandeln, Dezimalseparator muss '.' sein */
            float fVal = atof(buf);
        }
    }

    /* Datei schließen */
    fclose(f);
}

GUID erzeugen

// rpcrt4.lib für RpcStringFree() nicht vergessen
CString GetGUID()
{
   GUID guid;
   CoCreateGuid(&guid);

   BYTE *str;
   UuidToString((UUID*)&guid, &str);
 
   CString GUIDStr((LPTSTR)str);

   RpcStringFree(&str);

   return GUIDStr;
}
  • eine weitere Möglichkeit bietet folgendes ausführliches Beispiel auf CodeProject: Link

Objektverwaltung mittels CList

  • neben std::vector gibt es unter MS Visual Studio noch ein Objekt, was zur Verwaltung von Objektlisten dient: die Template Klasse CList
  • folgender Code erweitert die CList um nützliche Funktionen:
#pragma once
//---------------------------------------------------------------------------
#ifndef CListeH
#define CListeH
//---------------------------------------------------------------------------
template <class T> class CListe : public CList<T, T>
{
  public:
    
    // destruktor, damit auch alle Objekte beim Zerstören der Liste
    // mit aus dem Speicher entfernt werden
    virtual ~CListe()
    {
        delete_all();
    };

    // fügt Objekt vom Typ T der Liste hinzu
    void Add(T I)
    {
        AddTail(I);
    };

    // gibt Objekt bei iIndex zurück
    T Item(int iIndex)
    {
        T R = NULL;

        if ((iIndex < GetCount()) && (iIndex >= 0))
        {
           R = ((T)GetAt(FindIndex(iIndex)));
        }

        return R;
    };

    // gibt ein Objekt anhand seiner ID zurück (insofern es eine Eigenschaft iId hat)
    T Item_from_Id(int iId)
    {
        T R = NULL;
  
        for (int i=0; i<GetCount(); i++)
        {
            T RTemp = ((T)GetAt(FindIndex(i)));
    
            if (RTemp)
            {
                if (RTemp->iId == iId)
                {
                    R = RTemp;
                    break;
                }
            }
        }
  
        return R;
    };

    // löscht ein Item anhand seines Indexes aus der Liste und aus dem Speicher
    void _delete(unsigned int uiIndex)
    {
         T R=((T)GetAt(FindIndex(uiIndex)));

         RemoveAt(FindIndex(uiIndex));

         if (R)
         {
            delete R;
            R = NULL;
         }
    };

    // löscht ein Item anhand der Id aus der Liste und aus dem Speicher
    // (auch mehrere mit der selben Id)
    // gibt die Anzahl der gefundenen (gelöschten) Items zurück
    int _delete_by_id(int iId)
    {
        int iAnzDelObj = 0;

        for (int i=0; i<GetCount(); i++)
        {
            T R=((T)GetAt(FindIndex(i)));

            if (R)
            {
              if (R->iId == iId)
              {
                _delete(i);
                i--;
                iAnzDelObj++;
              }
            }
        }

        return iAnzDelObj;
   };

    // löscht alle Objekte in der Liste und im Speicher
    void delete_all()
    {
        while (GetCount() > 0)
        {
            _delete(0);
        }
    };

    //  GetNewBlockId() gibt eine gültige freie Block-ID aus der Liste zurück
    int GetNewBlockId()
    {
        bool bFound = true;
        int  iIdCount = 0;

        while (bFound)
        {
            iIdCount++;
            bFound = false;
          
            for (int i=0; i<GetCount(); i++)
            {
                if (Item(i)->iId == iIdCount)
                {
                    bFound = true;
                    break;
                }
                else
                {
                    bFound = false;
                }
            }
        }

        return iIdCount;
    };
};
//---------------------------------------------------------------------------
#endif
  • verwendet wird das Ganze wie folgt:
// Beispielobjekt zur Verwaltung durch CListe deklarieren
class TXYValue
{
public:
  double x;
  double y;
  int iId;

  TXYValue(double dx, double dy);
  {
       x = dy;
       y = dy;
  }

  ~TXYValue(void);
};

// Liste erzeugen
CListe<TXYValue*> *pCList = new CListe<TXYValue*>;

// Element zu Blockliste hinzufügen
TXYValue *pXY = new TXYValue();
pXY->iId = pCList->GetNewBlockId();
pCList->Add(pXY);

// Element anhand seines Indexes ermitteln
int iIndex = 2;
TXYValue *pXY = pBlockList->Item(iIndex);

// Element anhand seiner ID ermitteln
int iID = 2;
TXYValue *pXY = pBlockList->Item_from_Id(iID);

// Element anhand seines Indexes löschen
int iIndex = 0;
pCList->_delete(iIndex);

// Element anhand seiner ID löschen
int iID = 1;
int iDelElements = pCList->_delete_by_id(iID);

// nur Elemente der Liste löschen
pCList->delete_all();

// Liste und alle Elemente der Liste zerstören
delete pCList;

Stringkonvertierung ANSI/ASCII Unicode

Quellen:

CodeGuru.com
Microsoft

  • ANSI zu Unicode
char *ansistr = "Hello" // Quelle
BSTR unicodestr; // Ziel

int lenA = lstrlenA(ansistr);
int lenW;

lenW = ::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, 0, 0);
if (lenW > 0)
{
  unicodestr = ::SysAllocStringLen(0, lenW);
  ::MultiByteToWideChar(CP_ACP, 0, ansistr, lenA, unicodestr, lenW);
}
else
{
   // Fehler
}

// hier Strings auswerten
...

// abschließend String löschen
::SysFreeString(unicodestr);
  • Unicode zu ANSI
BSTR unicodestr = 0; // Quelle
char *ansistr; // Ziel

// Funktion zum Füllen des Quellstrings
SomeCOMFunction(&unicodestr);

int lenW = ::SysStringLen(unicodestr);
int lenA = ::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, 0, 0, NULL, NULL);
if (lenA > 0)
{
  ansistr = new char[lenA + 1]; // mit null terminator
  ::WideCharToMultiByte(CP_ACP, 0, unicodestr, lenW, ansistr, lenA, NULL, NULL);
  ansistr[lenA] = 0; // hier kann der null terminator gesetzt werden
}
else
{
    // Fehler
}

// hier Strings auwerten
...

// abschließend Strings löschen
delete[] ansistr;
::SysFreeString(unicodestr);

2. Beispiel:

  • ASCII zu Unicode
char cAsciiStr[] = "ASCIIText";
wchar_t wcUnicodeStr[1024];
MultiByteToWideChar(CP_ACP, 0, cAsciiStr, -1, wcUnicodeStr, 1024);
  • Unicode zu ASCII
char cAsciiStr[1024];
wchar_t wcUnicodeStr[] = L"UnicodeText";
WideCharToMultiByte(CP_ACP, 0, wcUnicodeStr, -1, cAsciiStr, 1024, NULL, NULL);

Zufallszahlen erzeugen

  • TRandom.h
#pragma once

class TRandom
{
public:
	TRandom(void);
	~TRandom(void);

	// reset random seed
	void Reset();
	// random number between 0..1
	double GetRandom();
	// dMin >= random number <= dMax
	double GetRandomDouble(double dMin, double dMax);
	// iMin >= random int number <= iMax
	int GetRandomInt(int iMin, int iMax);
	// random bool, true or false
	bool GetRandomBool();
};
  • TRandom.cpp
#include "TRandom.h"
#include <time.h>
#include <stdlib.h>

TRandom::TRandom(void)
{
	srand((unsigned)time(NULL));
}

TRandom::~TRandom(void)
{
}

// reset random seed
void TRandom::Reset()
{
	srand((unsigned)time(NULL));
}

// random number between 0..1
double TRandom::GetRandom()
{
	return (double)rand()/(double)RAND_MAX;
}

// dMin >= random double number <= dMax
double TRandom::GetRandomDouble(double dMin, double dMax)
{
	return dMin + this->GetRandom() * (dMax - dMin);
}

// iMin >= random int number <= iMax
int TRandom::GetRandomInt(int iMin, int iMax)
{
	return iMin + this->GetRandom() * (iMax - iMin);
}

// random bool, true or false
bool TRandom::GetRandomBool()
{
	return (this->GetRandom() < 0.5);
}