Zahl durch Punkte trennen
-
Hallo,
ich bin ein Anfänger in C++ und möchte folgendes gerne wissen:
Ich habe in einem Label eine Zahl stehen. Nur ist diese Zahl immer so groß, dass es sehr uinübersichtlich ist (also es schwer zu lesen ist, wie viele Nullen etc. da stehen). Ich möchte gerne, dass an die entsprechenden Stellen Punkte gesetzt werden. Also, dass z.B.: statt
1000000 da steht: 1.000.000.Kann mir vielleicht jemand helfen?
Danke.
Lg,
chilli
-
Hallo
Es hindert dich nichts daran, die Formatfunktionen für Fließkommazahlen dafür zu verwenden : FloatToStr und Konsorten. Siehe BCB-Hilfe und Suchfunktion hier im BCB-Forum.
bis bald
akari
-
"Bastel Dir doch eine Komponente:
//Headerdatei: DirLabel.h
//---------------------------------------------------------------------------
#ifndef DirLabelH
#define DirLabelH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <StdCtrls.hpp>
//---------------------------------------------------------------------------
typedef void __fastcall (__closure *TOnCaptionChange)(AnsiString NewCaption);
//---------------------------------------------------------------------------
class PACKAGE TIntFormat : public TPersistent
{
private:
Boolean FOnlyValues;
Boolean FIsInt;
char FBlockDelimiter;
int FBlockSize;
AnsiString FPrefix,FSuffix;
void __fastcall SetBlockSize(int BS);
public:
__fastcall TIntFormat(void);
void __fastcall SetFIsInt(Boolean Value);
protected:
__published:
__property Boolean IsInt={read=FIsInt};
__property Boolean OnlyValues={read=FOnlyValues,write=FOnlyValues,default=false};
__property char BlockDelimiter={read=FBlockDelimiter,write=FBlockDelimiter,default='.'};
__property int BlockSize={read=FBlockSize,write=SetBlockSize,default=3};
__property AnsiString Prefix={read=FPrefix,write=FPrefix};
__property AnsiString Suffix={read=FSuffix,write=FSuffix};
};
//---------------------------------------------------------------------------
class PACKAGE TIntLabel : public TLabel
{
private:
TIntFormat FIntFormat;
virtual System::AnsiString __fastcall GetLabelText();
protected:
void __fastcall WndProc(TMessage& Msg);
public:
__fastcall TIntLabel(TComponent Owner);
__fastcall ~TIntLabel();
__published:
__property TIntFormat *Format={read=FIntFormat,write=FIntFormat};
};
//---------------------------------------------------------------------------
#endif//CPP- Datei Dirlabel.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop#include "DirLabel.h"
#include "filectrl.hpp"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck wird benutzt, um sicherzustellen, daß die erzeugten Komponenten keine
// rein virtuellen Funktionen haben.
////---------------------------------------------------------------------------
__fastcall TIntFormat::TIntFormat(void)
:TPersistent()
{
FOnlyValues=false;
FIsInt=false;
FBlockDelimiter='.';
FBlockSize=3;
FPrefix="";
FSuffix="";
}
//---------------------------------------------------------------------------
void __fastcall TIntFormat::SetBlockSize(int BS)
{
if (BS>0)
FBlockSize=BS;
}
//---------------------------------------------------------------------------
void __fastcall TIntFormat::SetFIsInt(Boolean Value)
{
FIsInt=Value;
}
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TIntLabel )
{
new TIntLabel(NULL);
}
//---------------------------------------------------------------------------
__fastcall TIntLabel::TIntLabel(TComponent Owner)
: TLabel(Owner)
{
FIntFormat=new TIntFormat();
}
//---------------------------------------------------------------------------
__fastcall TIntLabel::~TIntLabel()
{
delete FIntFormat;
}
//---------------------------------------------------------------------------
void __fastcall TIntLabel::WndProc(TMessage& Msg)
{ AnsiString NewCaption;
if (Msg.Msg==WM_SETTEXT)
{ NewCaption=AnsiString((char*)Msg.LParam).Trim();
if (FIntFormat->OnlyValues)
{ if (NewCaption.ToIntDef(0)==NewCaption.ToIntDef(1))
{ FIntFormat->SetFIsInt(true);
TLabel::WndProc(Msg);
}
else
{ //Aenderung ignorieren
}
}
else
{ FIntFormat->SetFIsInt((NewCaption.ToIntDef(0)==NewCaption.ToIntDef(1)));
TLabel::WndProc(Msg);
}
}
else
{ TLabel::WndProc(Msg);
}
}
//---------------------------------------------------------------------------
System::AnsiString __fastcall TIntLabel::GetLabelText()
{
AnsiString ValStr;
if (FIntFormat->IsInt)
{ if (FIntFormat->BlockDelimiter!='\0')
{ ValStr=Caption.Trim();
for (int i=ValStr.Length()-(FIntFormat->BlockSize-1);i>1;i-=FIntFormat->BlockSize)
{ if (i>1)
{ if (ValStr[i - 1]=='-')
{ break;
}
}
ValStr.Insert(AnsiString(FIntFormat->BlockDelimiter),i);
}
return FIntFormat->Suffix + ValStr + FIntFormat->Prefix;
}
else
{ return FIntFormat->Suffix + Caption + FIntFormat->Prefix;
}
}
else
{ if (FIntFormat->OnlyValues)
{ return "NoValue";
}
else
{ return FIntFormat->Suffix + Caption + FIntFormat->Prefix;
}
}
}
//---------------------------------------------------------------------------
namespace Dirlabel
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TIntLabel)};
RegisterComponents("MyTools", classes, 0);
}
}
//---------------------------------------------------------------------------Macht etwas Mühe, ist aber universell nutzbar.
Gruss
Frank
-
na das sieht ja gut aus :p
-
FloatToStrF macht das von allein, wenn man die richtigen Parameter benutzt, z.B.
FloatToStrF( 100000000, ffNumber, 18, 0 )
-
Danke für die vielen Antworten. Ich werd' die Vorschläge jetzt mal ausprobieren.
-
hey, also das funktioniert super!
Mein einziges Problem ist jetzt, dass ich den Code auch nochmal irgentwie umkehren muss:
Label1->Caption=FloatToStrF (Zahl, ffNumber, 18, 0); Zahl2=StrToInt(????((Label1->Caption), ffNumber, 18, 0));
Ich hab' für die Fragegezeichen mal StrFToFloat eingesetzt. Das kennt der compiler aber nicht. Was kann ich tun?
Lg,
chilli
-
Warum arbeitest Du nicht weiter mit der Variable Zahl?
-
es geht eigentlich darum, dass ich aus einem label, die eine solche Formatierung beinhaltet, eine Zahl machen kann. Das ist nicht immer die gleiche Zahl wie die Variable. Deswegen will ich den Eintrag aus dem Label in eine neue Variable packen.
-
Handelt es sich denn um Float oder Int bei Label->Caption.
Bei letzteres '.' durch '' ersetzen und dann StrToInt. Try and catch nicht vergessen.
Alternativ durch eine Schleife laufen lassen und neuen String somit erstellen.
-
Hallo chilli,
die Umkehrfunktion heißt einfach "StrToFloat" (ohne F dazwischen - das F bei "FloatToStrF" steht für 'Formatted'):
double zahl = StrToFloat(Label1->Caption);
-
hallo,
danke schonmal für die Antworten.
@TH69: Das kann ich leider nicht so machen, weil die Zahl (z.B. 1.250.000) zwei Punkte enthält. Da erhalte ich dann die Fehlermeldung, dass diese Zahl keine gültige Fließkommazahl, also float, ist.
@Mankind: Es handelt sich um Int. Meine Frage: wie kann ich denn nun die Punkte, die ja jeweils an anderen Stellen sitzen, durch '' ersetzen? Hab in der Suche leider nichts passendes gefunden.
-
mit StringReplace kannst du bestehende Zeichenketten in andere (auch leer) ersetzten
http://docwiki.embarcadero.com/VCL/de/AnsiStrings.StringReplace
-
Hallo,
ich habe jetzt mal folgendes ausprobiert und eine Fehlermeldung zur 6. Zeile (extern etc.) erhalten:Unit1.cpp:
#include "System.hpp" #include "SysUtils.hpp" LPCTSTR s = AnsiString (Label1->Caption).c_str(); extern PACKAGE System::AnsiString __fastcall StringReplace(const System::AnsiString s, const System::AnsiString OldPattern ('.'), const System::AnsiString NewPattern (' '), Sysutils::TReplaceFlags Flags);
Fehlermeldung:
[C++ Error]: Declaration syntax error.
Der Cursor stand dabei bei dem ersten Mal System::
Lg,
-
kleiner Tipp.
Bleib vorerst bei Konsolenanwendungen.
Lerne mit einem guten Buch oder Tutorial die Grundlagen.
Dan weisst du auch wie man eine Funktion richtig anwendet.Wenn du die Grundlagen mit Funktionen/Klassen/variablen etc beherrscht, schau dir langsam die vcl (GUI-Bibliothek des C++ Builder) an.
Nur Copy&Paste funktioniert nicht.
-
hallo,
für euch scheint dieser Vorgang doch relativ einfach zu sein. Kann nicht bitte jemand kurz mal einen code dazu reinstellen? Ich weiß, dass dieser Weg nicht so toll ist, aber wir müssen von der Schule aus, ein Programm schreiben und haben dafür den Borland C++ Builder 1 vorgesetzt bekommen.
Ich bin zurzeit wirklich verzweifelt. Wir müssen das Programm bis zum Ende der Ferien fertigstellen. Kann mir nicht netterweise jemand helfen?
Ich habe mir auch schon ein Buch besorgt und dieses durchgearbeitet (C++ für Kids), jedoch hat mir dies in diesem Zusammenhang nicht recht weitergeholfen.Lg,
chilli
-
Hallo,
ich bin's nochmal. Ich habe mir jetzt mal überlegt, wie man den direkt auf Zeichen zugreifen kann.
Also durch folgenden Code kriege ich die Punkte weg, doch nun habe ich Leerzeichen, weil ich '' nicht schreiben darf:
N=1; while (N < 100) { if (test[N]=='.') { test[N]=' '; //hier darf ich nicht =='' schreiben, weil immer ein parameter angegeben werden muss } N++; }
Dadurch, dass dort noch Leerzeichen sind, kann ich es immer noch nicht in eine int verwandeln.
-
so,
ich hab' mir jetzt nach langem ausprobieren selber ne Lösung zusammengebastelt. Ist zwar nicht schön, aber funktioniert:
String test; test=Label1->Caption; try { N=1; Edit1->Text=""; while (N < 100) { if ((test[N]!='.') && (test[N]!=!isdigit)) { Edit1->Text= (Edit1->Text) + (test[N]); } else if ((test[N]!='.') && (test[N]==!isdigit)) { N=100; } N++; } test=Edit1->Text; Zahl2=StrToInt (test); } catch (...) { ShowMessage ("Vorbei"); } ShowMessage (test);
Lg,
chilli
-
Bist du mit StringReplace nicht zurechtgekommen? Der Aufruf ist recht simpel:
String strZahl = StringReplace(Label1->Caption, ".", "", (TReplaceFlags) rfIgnoreCase);
In der BCB-Hilfe findest du weitere Infos.
-
@Chilli
Warum nimmst Du nicht einfach die Komponente?
Da kannst Du über TIntLabel->Caption IMMER die eingetragene Zahl (integer) wieder auslesen!
das ist ja Sinn der Komponente:
- Belibige Int- Werete eintragen
- Anzeige erfolgt "formatiert"
- In Caption ist immer der eingetragen Zahlenwert verfügbar.Gruss
frankPS:
das geht genauso ähnlich auch mit double- Zahlen zu machen.ich nutze auch dafür ne passende zweite Kompomente (dann z.B. mit Masseinheiten dran; oder als Winkelanzeige [Eingabe Bogenmass => Anzeige Grad, gerundet])....