String löschen mit .clear()

OP #7451646
Lesenswert?

Hallo,

bin mit dem String durcheinander gekommen. Idee ist, über Konsole werden ganze Zahlen eingetippt, daraus soll eine gerade und ungerade Summe gebildet werden, hier ein Ausschnitt;

1
// *ptrToArray - pointer to the data array
2
// arrayLength - length of the array
3
// vector - contains indices of the array with value of space '32'
4
void numberSeparation(char *ptrToArray, int arrayLength, std::vector<int> vector)
5
{
6
    std::string tempString;
7
    int i = 0;  //index for tempBuffer to store number temporarly
8
    int z = 0;  //index of vector, containing the space locations
9
    double evenSum = 0;
10
    double oddSum = 0;
11

12
    for(int y = 0; y < arrayLength;)
13
    {
14
        // copy data only if no space currently read
15
        if(ptrToArray[y] != 32)
16
        {
17
            tempString[i] = ptrToArray[y];
18
            i++;
19
        }
20
        y++;
21

22
        //get last char
23
        if(y == arrayLength)
24
        {
25
            tempString[i] = ptrToArray[y];
26
        }
27

28
        // if case space index present or end of string reached
29
        if((y == vector[z]) || (y == arrayLength))
30
        {
31
            if(stoi(tempString)%2 == 0)
32
            {
33
                 evenSum += stoi(tempString);
34
                 std::cout<<"evenSum : "<<evenSum<<std::endl;
35
            }
36
            else
37
            {
38
                oddSum += stoi(tempString);
39
                std::cout<<"oddSum : "<<oddSum<<std::endl;
40
            }
41

42
            tempString.clear();
43

44
            // increment the vector index only till the last valid entry
45
            if((vector.size()) > z)
46
            {
47
                std::cout<<"z : "<<z<<std::endl;
48
                z++;
49
            }
50
            
51
            i = 0;
52
        }
53
        
54
    }
55

56
    std::cout<<"even sum : "<<evenSum<<std::endl;
57
    std::cout<<"odd sum : "<<oddSum<<std::endl;
58

59
}

Problem was ich habe ist, dass anscheinend mein tempString nicht immer komplett gelöscht wird

1
provide set of whole munbers : 
2
2 4 3 88 7 4 65 06
3
evenSum : 2
4
z : 0
5
evenSum : 6
6
z : 1
7
oddSum : 3
8
z : 2
9
evenSum : 94
10
z : 3
11
evenSum : 172 --> hier wird statt mit 7 und oddSum mit 78 und evenSum gearbeitet, d.h. der 88 von vorher wird überschrieben !!
12
z : 4
13
evenSum : 220
14
z : 5
15
oddSum : 68
16
z : 6
17
evenSum : 226
18

19
even sum : 226
20
odd sum : 68
21

22
numbers entered: 2 4 3 88 7 4 65 06

VG Michael

#7451651
Lesenswert?

Michael S. schrieb:

Problem was ich habe ist, dass anscheinend mein tempString nicht immer komplett gelöscht wird

Ja, nicht nur.

Problem ist, dass du völlig am schwimmen bist bei deiner Hausaufgabe.

Nett auch der nutzlos mitgeführte vector.

Da ist das Reingrätschen in tempString ja noch harmlos.

Mach halt den Programmierkurs nochmal, bisher hast du nicht verstanden, wie man programmiert.

(Firma: Torrox.de) #7451655
Lesenswert?

Du kannst nicht auf das i'te Zeichen eines leeren Strings zugreifen.

1
  tempString.push_back(ptrToArray[y]);

wäre eine gültige Methode. Viele STLs haben eine Möglichkeit, solche Fehler zur Laufzeit zu erkennen. Guck mal, welche Möglichkeiten Dein Compiler hat. Das würde Dir eine Menge Zeit sparen.

Namen, wie ptrToArray haben kaum Informationen, weil nur der Typ im Namen kodiert ist, aber nicht der Zweck / Rolle des Parameters.

(Firma: Torrox.de) #7451664
Lesenswert?

Michael S. schrieb:

danke für eure Inputs, dass mit dem push_back hat jetzt funktioniert. Ich dachte eigentlich, da ich die einzelnen String Elemente mit string[index] ausgeben kann, dann könnte ich ja auch die Daten genau so rein schreiben.

Du kannst mit dem Index-Operator auf vorhandene Elemente der Zeichenkette zugreifen. Wenn die Zeichenkette leer ist, dann geht das dem entsprechend nicht: https://en.cppreference.com/w/cpp/string/basic_string

#7451705
Lesenswert?

Hallo Michael,

eigentlich wollte ich nach dem Fehler suchen, aber da ist ja einiges recht merkwürdig. Irgendwie ein bischen C, ein bischen C++ und viele Ungereimtheiten bzw. Dinge, deren Sinn ich nicht ganz verstehe. Unten ein Vorschlag (einfaches C++17 ohne Schnickschnack und Fehlerprüfung). Die Ausgabe selbst habe ich mal aus der Funktion rausgenommen.

1
#include <iostream>
2
#include <sstream>
3
#include <string>
4
#include <vector>
5

6
std::pair<int, int> calculateSums(const std::string& input_string)
7
{
8
  std::stringstream ss(input_string);
9
  
10
  std::vector<int> numbers (
11
    std::istream_iterator<int>{ ss },
12
    std::istream_iterator<int>{}
13
  );
14

15
  int evenSum = 0;
16
  int oddSum = 0;
17

18
  for(int number : numbers)
19
  {
20
    if(number % 2 == 0)
21
      evenSum += number;
22
    else
23
      oddSum += number;
24
  }
25

26
  return { evenSum, oddSum };  
27
}
28

29
int main()
30
{
31
  auto [even, odd] = calculateSums("2 4 3 88 7 4 65 06");
32
  
33
  std::cout<<"even sum : " << even << '\n';
34
  std::cout<<"odd sum : " << odd << '\n';
35
}
#7452320
Lesenswert?

Michael S. schrieb:

was passiert hier, werden die Zahlen direkt aus dem String im Vector als int abgelegt ?

der Vector hat einen Konstruktor mit zwei Iteratoren, d.h. der Vektor wird mit den von den Iteratoren gelieferten Werten aufgebaut. der begin-Iterator ist ein istream-iterator, der integer-Werte aus dem input-stream liest. der end-Iterator ist der generische "eof"-Iterator dazu.

d.H. der vector wird mit allen aus dem sstream lesbaren integern befüllt.

Wenn man das noch optimieren mag, das Zwischenspeichern im vektor ist eigentlich unnötig, die odd/even-Schleife könnte auch direkt über den istream_iterator<int> laufen.

1
  for(auto it=std::istream_iterator<int>{ ss }; it!= std::istream_iterator<int>{}; ++it)
2
  {
3
    if(*it % 2 == 0)
4
      evenSum += *it;
5
    else
6
      oddSum += *it;
7
  }
#7452343
Lesenswert?

Michael S. schrieb:

was passiert hier, werden die Zahlen direkt aus dem String im Vector als int abgelegt ?

Ja. Es gibt aber noch unzählige andere Methoden, einen solchen String zu splitten/parsen und die Werte in einem Container (wie hier std::vector) abzulegen, von C-Style bis zu STL-Kunststücken und Bibliotheken wie Boost. Die Vorgehensweise mit einem String-Stream ist eben einfach - und man benötigt keine expliziten Schleifen. Dabei werden eigentlich zwei Dinge genutzt: Erstens, dass man mit std::stringstream mit einem String wie mit einem Stream arbeiten kann, zweitens, dass einer der Konstruktoren von std::vector ein Start- und End-Iterator-Paar entgegennimmt (unten "first" und "last", der Allocator ist optional, den kannst du ignorieren).

1
template<class InputIt>
2
vector(InputIt first, InputIt last, const Allocator& alloc = Allocator());

Wenn man das von Hand aufdröselt, ohne den speziellen Konstruktor von std::vector zu benutzen, sieht es in etwa so aus:

1
std::vector<int> numbers;
2

3
std::istream_iterator<int> start_it(ss);
4
std::istream_iterator<int> end_it;
5

6
for(auto it = start_it; it != end_it; ++it)
7
{
8
  numbers.emplace_back(*it);
9
}

Den Vektor brauchen wir eigentlich nicht ...

1
for(auto it = start_it; it != end_it; ++it)
2
{
3
  if(*it % 2 == 0)
4
    evenSum += *it;
5
  else
6
    oddSum += *it;
7
}

Wenn Du

1
  std::istream_iterator<int> start_it(ss);

durch

1
  std::istream_iterator<int> start_it(std::cin);

ersetzt, wird statt des String-Streams der Standard-Inputstream verwendet; du kannst dann in der Konsole die Werte eingeben (Beenden der Eingabe mit Ctrl-Z + Enter bzw. Ctrl-D + Enter - oder einfach irgendeinen Buchstaben eingeben + Enter).

Noch eine Möglichkeit, die Werte in einen std::vector zu bekommen, wäre

1
  std::copy(std::istream_iterator<int>{ss}, {}, std::back_inserter(numbers)); // zu {} siehe unten

BTW: Du solltest noch

1
#include <iterator>

oben einfügen.

Auch kann man in meinem Beispiel ein wenig abkürzen:

1
std::vector<int> numbers(std::istream_iterator<int>{ss}, {});

Der Compiler kommt hier von selbst darauf, dass {} der passende End-Iterator sein soll (etwas vereinfacht ausgedrückt).

https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Die_STL/_Iteratoren

https://www.kompf.de/cplus/artikel/stream4.html

https://cplusplus.com/reference/sstream/stringstream/

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren