Kapitel 5

Alle Codedateien dieses Kapitels herunterladen

05_1_1_Textarbeit.cpp

Datei herunterladen

#include <iostream>
#include <string>

int main()
{
  // Fehlerhafte Ausgabe
  int year = 2014;
  std::string output = "Weltmeister " + year;
  std::cout << output << std::endl;

  // Korrigierte Ausgabe
  output = "Weltmeister " + std::to_string(year);
  std::cout << output << std::endl;

  // Mehrzeilige Ausgabe
  std::string output3 = "Ein sehr langer Text, "
    "bestehend aus mehr als einem Satz. Die Verteilung "
    "auf mehrere Codezeilen hat aber keine Auswirkung auf "
    "die Ausgabe. Dort ist es immer noch nur eine Zeile!";
  std::cout << output3 << std::endl;

  // Ausgabe von Sonderzeichen
  std::string mediaFolder = "C:\\Windows\\Media";
  std::cout << mediaFolder << std::endl;

  std::string multiline = "Text\nauf\nmehreren\nZeilen";
  std::cout << multiline << std::endl;

  std::string quotes = "\"\"";
  std::cout << quotes << std::endl;

  std::string table = "1\t|2\t|3\t|\n"
    "-------------------------\n"
    "A\t|B\t|C\t|\n"
    "eins\t|zwei\t|drei\t|";
  std::cout << table << std::endl;

  // Zwischenfrage:
  std::cout << "Unter \"C:\\Windows\\\" finden Sie die Windows-Dateien." << std::endl;

  std::cout << "Das ist überraschend. äöü" << std::endl;

  // Zwischenfrage
  std::cout << "Das ist \201berraschend. \204\224\201" << std::endl;

  return 0;
}

05_1_2_Umlaute.cpp

Datei herunterladen

#include <iostream>
#include <string>

int main()
{
  std::cout << "Das ist überraschend" << std::endl;
  std::cout << "Das ist \201berraschend" << std::endl;

  std::cout << "Typisch fiese Kater würden Vögel bloß zum Jux quälen" << std::endl;
  std::cout << "Typisch fiese Kater w\201rden V\224gel blo\341 zum Jux qu\204len" << std::endl;

  return 0;
}

05_2_Substrings.cpp

Datei herunterladen

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& str)
{
  std::vector<std::string> parts;
  size_t start = 0;
  size_t end = str.find(',');
  // Wenn die Suche zu keinem Ergebnis führt, nimmt der
  // Rückgabewert den speziellen Wert npos an
  while (end != std::string::npos)
  {
    parts.push_back(str.substr(start, end - start));
    start = end + 1;
    end = str.find(',', start);
  }
  parts.push_back(str.substr(start, end));
  return parts;
}

int main()
{
  std::string example = "Ein Beispiel";
  example.at(4);  // B
  example.at(3);  // Das Leerzeichen
  // example.at(23);  // Zugriffsfehler

  // Anfangsindex und Länge angegeben. Ergebnis: Bei
  std::string sub1 = example.substr(4, 3);
  // Ab Index 4 alles bis zum Ende. Ergebnis: Beispiel
  std::string sub2 = example.substr(4);
  // Alles außer dem letzten Zeichen. Ergebnis: Ein Beispie
  std::string sub3 = example.substr(0, example.size()-1);

  // Alles bis zum ersten Leerzeichen. Ergebnis: Ein
  std::string sub4 = example.substr(0, example.find(' '));
  // Alles nach dem ersten Leerzeichen. Ergebnis: Beispiel
  // Um das Leerzeichen zu überspringen, 1 addieren
  std::string sub5 = example.substr(example.find(' ') + 1);

  std::vector<std::string> list = split("rad,bahn,auto");
  return 0;
}

05_3_1_Parsing.cpp

Datei herunterladen

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& str,
  char delimiter = ',')
{
  std::vector<std::string> parts;
  size_t start = 0;
  size_t end = str.find(delimiter);
  // Wenn die Suche zu keinem Ergebnis führt, nimmt der
  // Rückgabewert den speziellen Wert npos an
  while (end != std::string::npos)
  {
    parts.push_back(str.substr(start, end - start));
    start = end + 1;
    end = str.find(delimiter, start);
  }
  parts.push_back(str.substr(start, end));
  return parts;
}

int parseDate(const std::string& str)
{
  std::vector<std::string> parts = split(str, '.');
  if (parts.size() != 3)
  {
    std::cerr << "Datum ung\201ltig: " << str << std::endl;
    return -1;
  }
  int day = std::stoi(parts.at(0));
  int month = std::stoi(parts.at(1));
  int year = std::stoi(parts.at(2));
  return year * 10000 + month * 100 + day;
}

int main()
{
  std::vector<std::string> inputs = {
    "4.6.2003",
    "17.11.1993",
    "03.09.2025",
    "invalid"
  };
  std::vector<int> outputs = {
    20030604,
    19931117,
    20250903,
    -1
  };
  for (int i = 0; i < outputs.size(); i++)
  {
    if (outputs.at(i) != parseDate(inputs.at(i)))
    {
      std::cerr << "Parsingfehler bei " << inputs.at(i)
        << std::endl;
      return 1;
    }
  }
  return 0;
}

05_3_2_ParsingChecks.cpp

Datei herunterladen

#include <iostream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& str,
  char delimiter = ',')
{
  std::vector<std::string> parts;
  size_t start = 0;
  size_t end = str.find(delimiter);
  // Wenn die Suche zu keinem Ergebnis führt, nimmt der
  // Rückgabewert den speziellen Wert npos an
  while (end != std::string::npos)
  {
    parts.push_back(str.substr(start, end - start));
    start = end + 1;
    end = str.find(delimiter, start);
  }
  parts.push_back(str.substr(start, end));
  return parts;
}

int parseDate(const std::string& str)
{
  std::vector<std::string> parts = split(str, '.');
  if (parts.size() != 3)
  {
    std::cerr << "Datum ung\201ltig: " << str << std::endl;
    return -1;
  }
  int day = std::stoi(parts.at(0));
  int month = std::stoi(parts.at(1));
  int year = std::stoi(parts.at(2));
  // Generelle Grenzen überprüfen
  if (year <= 0 || month < 1 || month > 12 || day < 1 || day > 31)
  {
    std::cerr << "Datum ung\201ltig: " << str << std::endl;
    return -1;
  }
  // Monatsspezifische Grenzen überprüfen
  if (month == 2 && day > 29 || month == 4 && day > 30
    || month == 6 && day > 30 || month == 9 && day > 30
    || month == 11 && day > 30)
  {
    std::cerr << "Datum ung\201ltig: " << str << std::endl;
    return -1;
  }
  return year * 10000 + month * 100 + day;
}

int main()
{
  std::vector<std::string> inputs = {
    "4.6.2003",
    "17.11.1993",
    "03.09.2025",
    "invalid"
  };
  std::vector<int> outputs = {
    20030604,
    19931117,
    20250903,
    -1
  };
  for (int i = 0; i < outputs.size(); i++)
  {
    if (outputs.at(i) != parseDate(inputs.at(i)))
    {
      std::cerr << "Parsingfehler bei " << inputs.at(i)
        << std::endl;
      return 1;
    }
  }
  return 0;
}

05_5_1_Map.cpp

Datei herunterladen

#include <iostream>
#include <string>
#include <map>

int main()
{
  std::map<std::string, int> market;
  market["tomato"] = 80;
  market["onion"] = 20;
  market["apple"] = 30;

  std::map<std::string, int> market2 = {
    { "tomato", 80 },
    { "onion", 20 },
    { "apple", 30 }
  };

  int count = market.at("onion");
  std::cout << "Count: " << count << std::endl;

  // Fünf Zwiebeln verkauft. Neuer Wert ist 15
  market["onion"] -= 5;

  // Die ersten Salatköpfe wurden angeliefert. Bis jetzt
  // war noch kein Element mit dem Schlüssel "salad" in der
  // Map, daher wird ein Eintrag mit dem Standardwert 0
  // angelegt und 10 addiert. Der Wert ist danach also 10
  market["salad"] += 10;

  std::cout << market["salad"] << std::endl;

  // Ausgabe aus der zweiten Map
  std::cout << market2["tomato"] << std::endl;

  return 0;
}

05_5_2_EncodeUmlauts.cpp

Datei herunterladen

#include <iostream>
#include <string>
#include <map>

const std::map<std::string, char> replacements = {
  {"ä", '\204'},
  {"Ä", '\216'},
  {"ö", '\224'},
  {"Ö", '\231'},
  {"ü", '\201'},
  {"Ü", '\232'},
  {"ß", '\341'}
};

std::string encodeUmlauts(std::string input)
{
  // Stringlänge zu einer Vorzeichenzahl konvertieren
  for (int i=0; i < static_cast<int>(input.size())-1; i++)
  {
    // Für die Sonderzeichen zwei Zeichen extrahieren
    std::string codepoint = input.substr(i, 2);
    // Wenn replacementMap.find() das Ergebnis nicht
    // findet, wird replacementMap.end() zurückgegeben
    if (replacements.find(codepoint) != replacements.end())
    {
      // Die zwei Zeichen an der Stelle i ersetzen:
      // Alles bis zur Stelle i, dann die Ersetzung und
      // dann den Rest nach den zwei Zeichen zusammenfügen.
      char replacementChar = replacements.at(codepoint);
      input = input.substr(0, i)
        + replacementChar + input.substr(i + 2);
    }
  }
  return input;
}

std::string decodeUmlauts(std::string input)
{
  for (int i = 0; i < input.size(); i++)
  {
    // Um das Element in std::map anhand des Wertes zu
    // finden, müssen Sie händisch durch die Map gehen
    for (std::pair<std::string, char> entry : replacements)
    {
      // Beim umgekehrten Weg müssen Sie nur jeweils ein
      // Zeichen ersetzen:
      if (input.at(i) == entry.second)
      {
        input = input.substr(0, i)
          + entry.first + input.substr(i + 1);
        // Zeichen wurde ersetzt. Das heißt Sie können die
        // Suche in der Map abbrechen und weitergehen
        break;
      }
    }
  }
  return input;
}

int main()
{
  std::cout << encodeUmlauts("Das ist überraschend.")
    << std::endl;
  // Ergebnis: "Das ist \201berraschend. \204\224\201"
  // Die Konsole gibt die Sonderzeichen damit korrekt aus.

  std::string input;
  while (true)
  {
    std::getline(std::cin, input);
    input = decodeUmlauts(input);
    if (input == "Überrasch mich")
    {
      std::cout << "Buhh!!" << std::endl;
    }
    if (input == "exit")
    {
      break;  // while-Schleife verlassen
    }
  }
  return 0;
}
// Hinweis für Profis: std::string hat auch eine replace()-
// Methode. Diese könnte man wie folgt oben verwenden:
// In decodeUmlauts():
//   input.replace(i, 2, 1, replacements.at(codepoint));
// In encodeUmlauts():
//   input.replace(i, 1, entry.first);

05_6_Arrays.cpp

Datei herunterladen

#include <iostream>

int main()
{
  int numbers[3];
  numbers[0] = 15;
  numbers[1] = 11;
  numbers[2] = 7;

  int numbers2[3] = { 20, 35, 9 };
  return 0;
}