Problem z pętlą do-while i ciągami string. c++


(Ada Safaryn) #1

Cześć mam mały problem, napisałam taki program, który ma wczytywać ciąg liczb całkowitych dodatnich aż do napotkania liczby ujemnej i dla każdego ciągu wypisywac komunikat, w zależności od długości tego ciągu, tylko nie wiem jaki dać warunek while(), mógłby mi ktos pomóc, z góry dzięki. A i jeszcze jedno pytanie, jak uwzględnić, żeby wczytywać ciąg do napotkania liczby ujemnej?

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	string a;
	
	do
	{
	
		cout<<"Podaj ciag= "; cin>>a;
	{
	int d=a.length();
	{
	
	if(d==1) cout<<"? 1"; else
	if(d==2) cout<<"? 2"; else
	if(d==3) cout<<"? 3"; else
	if(d==4)cout<<"? 4"; else
	cout<<"? 555";
}
	}

}
while (string a !=0)

return 0;
}

(Jim1961) #2

Sama sobie odpowiedziałaś: “…aż do napotkania liczby ujemnej…”, czyli:

while(a >= 0)


(enedil) #3

Nie do końca rozumiem o co chodzi w tym kodzie. Aby sprawdzić, czy w ciągu liczba jest ujemna musiałbyć wczytywać tablicę charów i w momencie, gdy znajdziesz ‘-’ przerwać wczytywanie:

char array[1000];
for (int i = 0; i < 1000; i++)
{
std::cin >> array[i];
if (array[i] == '-')
{
std::cout << "Napotkano cyfrę ujemną, przerywam wczytywanie";
i = 1000;
}
}

(enedil) #4

 

Serio?

while(/*string*/ a >= 0)

Chcesz porównywać stringa do unsigned?


(Jim1961) #5

łups!! miało być “d” zamiast “a”


(Ada Safaryn) #6

Dzięki za pomoc,

a polecenie brzmiało tak:

Wczytywać ciąg liczb całkowitych dodatnich aż do napotkania liczby niedodatniej. Dla każdej

z nich drukować:

 1 - dla liczb jednocyfrowych

 2 - dla liczb dwucyfrowych

 3 -dla liczb trzycyfrowych

 4 - dla liczb czterocyfrowych

 555 - dla pozostałych.

Jim1961: porównywanie do d nie działa…

mógłbyś mi to wytłumaczyć, przepraszam za kłopot, ale nie za bardzo rozumiem. Po co na koniec ustawiamy i=1000 ?

Proszę korzystać z opcji Edytuj , zamiast pisać post pod postem.

rgabrysiak


(Himek22) #7

W pętli for daliśmy warunek, żeby powtarzać dopóki i<1000, bo tablica ma długość 1000 (a nie chcemy wyjść poza tablicę, prawda?)

Tak więc i=1000 oznacza wyjście z pętli, gdyż wtedy warunek i<1000 nie będzie wówczas spełniony. To przypisanie jest w if-ie, wiec wyjście z pętli wczytujacej liczby nastąpi po wczytaniu ujemnej rozpoznawanej po minusie.

To tyle o tajemniczym i = 1000. Teraz przyczepie sie do jednego detalu :D.

Warunek w treści zadania jest dla niedodatniej, a nie ujemnej. Trzeba do ifa dodać jeszcze wykrywanie 0. Czyli

if (array[i] == '-' || array[i] == '0')

(enedil) #8

Nie można w nieskończoność wczytywać moim sposobem liczb. Przyjąłem, że maksimum, to tysiąc. Pętla for kończy się właśnie gdy i >= 1000. Niestety chyba nie do końca zrozumiałem zadanie, więc mój sposób się nie nadaje.


(kostek135) #9

@enedil


(Himek22) #10

Zaproponował bym coś takiego:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string a;
    cin >> a;
    while (a != "0" || a[0]!="-")
    {
          if (a.length() == 1) cout<<"1"<<endl;
          else if (a.length() == 2) cout<<"2"<<endl;
          else if (a.length() == 3) cout<<"3"<<endl;
          else if (a.length() == 4) cout<<"4"<<endl;
          else cout<<"555"<<endl;
	cin >> a;  
 }   
}

(Jim1961) #11

nie znam się, to się wypowiedziałem :stuck_out_tongue:

 

poniższy działa jak w treści zadania z posta #6

#include<iostream>
#include<cstring>

using namespace std;

int main()
{
	string a;
	int d = 0;
	do {
		if (d != 0){
			if (d < 5)
				cout << " ? " << d << endl;
			else
				cout << " ? 555" << endl;
		}
		cout << "podaj ciag: ";
		cin >> a;
		d = a.length();
 	} while (a[0] != '-' && a != "0");

 	return 0;
}

(Ada Safaryn) #12

Wielkie dzięki za pomoc :slight_smile:

Mam tylko ostatnie pytanie, ale chce to dobrze zrozumieć.

Czemu ciąg wprowadzamy dopiero po warunkach if ?

  1. cout "podaj ciag: ";
  2. cin a;

Proszę korzystać z opcji Edytuj , zamiast pisać post pod postem.

rgabrysiak


(Jim1961) #13

taki mały myk, żeby nie wyświetlać ilości znaków niczego co nie spełnia warunków w while’u … albo żeby ich nie sprawdzać dwa razy; dla porównania odpal sobie poniższe i wpisz coś z minusem, albo zero

// ...
int main()
{
	string a;
	int d;
	do {
		cout << "podaj ciag: ";
		cin >> a;
		d = a.length();
		if (d < 5)
			cout << " ? " << d << endl;
		else
			cout << " ? 555" << endl;

 	} while (a[0] != '-' && a != "0");

 	return 0;
}

po wpisaniu zera wyświetli się 1 i program zakończy się; przy wpisaniu np. -123 wyświetli się 4 i również się zakończy; a IMHO w tych wypadkach powinno się zakończyć bez wypisania tych ilości;

 

można to prawidłowo napisać też tak:

// ...
int main()
{
	string a;
	int d;
	while (true){
		cout << "podaj ciag: ";
		cin >> a;
		if (a[0] != '-' && a != "0"){
			d = a.length();
			if (d < 5)
				cout << " ? " << d << endl;
			else
				cout << " ? 555" << endl;
		} else {
			break; // kończy pętlę while
		}
 	};
 	return 0;
}

trochę bardziej … logicznie :wink:


([alex]) #14

Nie rozumiem czemu nie można zrobić tego zadania po ludzku?

#include <iostream>
#include <cmath>
using namespace std;

int main()
  {
   int x;
   while((cin>>x)&&(x>=0)) cout<<x<<" size: "<<(1+(x?floor(log10(x)):0))<<endl;
   return 0;
  }

(Jim1961) #15

@alex


(Drobok) #16

To że to newbie nie znaczy że masz mu dawać to co napisałeś, jeśli będzie miał wypisać 100 liczb a od 101 wypisywać coś innego to będzie przepisywać 100x to co mu dałeś z tymi ifami :stuck_out_tongue:

#include <iostream>
#include <cmath>
using namespace std;

int main()
  {
   double x,z;
   while((cin>>x)&&(x>=0)&&(z=1+floor(log10(x)))) cout<<x<<" size: "<<(z>4?555:z)<<endl;
   return 0;
  }

([alex]) #17

Bym to trochę inaczej zapisał:

#include <iostream>
#include <cmath>
using namespace std;

int main()
  {
   int x,z;
   while((cin>>x)&&(x>=0)) cout<<x<<' '<<((z=1+(int)floor(log10(x)))>4?555:z)<<endl;
   return 0;
  }

Skoro kazano wczytać liczbę to kombinowanie z napisem - przeważnie się nie opłaca, nieliczne wyjątki tylko potwierdzają regułę.