Formatting a CString in currency while typing in a edit box - formatting

I want to format a CString string in a currency while typing in a edit box using VISUAL C++ ... but I can't find a solution which works definitely...
typing for instance the first digit (i.e. 5), in the edit box it must appear 5,00 , typing the second digit 50,00 (the cursor must always be before the comma)... typing 56234 it must be 56.234,00 , typing the , the cursor must go after the comma position and it mustn't appear twice or more times of course... and writing i.e 5,65 it must appear 5,65
This is my code, but it doesn't work perfectly:
there's a variabile CString testo and a variable valuta which controls the edit box
void CCampovalutaDlg::OnEnChangeEdit1()
{
// TODO: Se si tratta di un controllo RICHEDIT, il controllo non
// invierà questa notifica a meno che non si esegua l'override della funzione CDialogEx::OnInitDialog()
// e venga eseguita la chiamata a CRichEditCtrl().SetEventMask()
// con il flag ENM_CHANGE introdotto dall'operatore OR nella maschera.
// TODO: Aggiungere qui il codice del gestore di notifiche del controllo
CString str = _T("0123456789");
CString comma = _T(",");
UpdateData();
testo.Replace(_T("."), _T(""));
if (testo.GetLength() > 3) testo.Insert(testo.GetLength() - 2, _T("."));
double cur = _wtof(testo);
if (testo.GetLength() == 1) testo.Format(_T("%.2f"), cur);
if (testo.FindOneOf(str) != -1) {
for (int i = testo.GetLength() - 6; i > 0; i -= 3) {
testo.Insert(i, _T("."));
}
}
UpdateData(FALSE);
valuta.SetSel(testo.GetLength() - 3, testo.GetLength() - 3);
}
Thanks for solving my problem
If I press the , it appears and the testo.Format doesn't make it appear a comma but a dot. And I can't type the decimal digits :-(

Related

How do I create a number Value to an radioButton in C# Visual Studio?

I'm having issue trying to assign different number values to a number a Radiobuttons, to then calculate together as a total sum into a textbox, but not sure where to start, im new to C# and not understanding to well, if anyone can provide a simple example I would be grateful
So far I've come up with something like this, just to try to assing the number value but cant get it to work, and not even sure how to add them together after?
Do I need to use: int?
int Basic, Reg, Pre
{
If RadioButton1.Checked = True Then
Basic = 10;
If RadioButton1.Checked = True Then
Reg = 15;
If RadioButton1.Checked = True Then
Pre = 20;
Looks mostly like Visual Basic. Try to find a beginner's tutorial on C# on the internet.
In this case the variables may not be assigned a value in the if statements. Unlike vb, you need to explicitly assign the default values to the variables before we try to add them at the end.
In C# If is if (most statements are lowercase) and the condition (the part that evaluates to true of false) is in parentheses.
In C# the assignment operator = is different from the comparison operator == which is used in many if statements. You could write
if (radioButton1.Checked == true)
but, since .Checked evaluates to true or false you can skip the == true.
if (radioButton2.Checked)
The code
private void button1_Click(object sender, EventArgs e)
{
int Basic = 0;
int Reg = 0;
int Pre = 0;
if (radioButton1.Checked == true)
Basic = 10;
if (radioButton2.Checked)
Reg = 15;
if (radioButton3.Checked)
Pre = 20;
txtTotal.Text = (Basic + Reg + Pre).ToString();
}
One last thing. ToString requires the method invoker (). vb is lazy about this. vb also allows you to skip it for constructors but you will need it in C#.
EDIT
Users can enter anything in a text box. To keep your code from blowing up it is best to use TryParse to verify a valid number. The first parameter is the string you want to convert. The second is a variable of the appropriate type to hold the converted value. The function returns True of False depending on the success of the conversion. The exclamation mark is Not in C#. If the conversion fails we inform the user and exit the method with return. If successful we continue to the multiplication with the converted values.
private void Button2_Click(object sender, EventArgs e)
{
if (!Double.TryParse(textbox5.Text,out double txt1))
{
MessageBox.Show("Please enter a valid number in textbox 5");
return;
}
if (!Double.TryParse(textbox6.Text,out double txt2))
{
MessageBox.Show("Please enter a valid number in textbox 6");
return;
}
double sum = txt1 * txt2;
textbox7.Text = sum.ToString();
}

additional logic to this exercise missing

Writing a basic program to count the number of words in a string. I've changed my original code to account for multiple spaces between words. By setting one variable to the current index and one variable to the previous index and comparing them, I can say "if this current index is a space, but the previous index contains something other than a space (basically saying a character), then increase the word count".
int main(int argc, const char * argv[]) {
#autoreleasepool {
//establishing the string that we'll be parsing through.
NSString * paragraph = #"This is a test paragraph and we will be testing out a string counter.";
//we're setting our counter that tracks the # of words to 0
int wordCount = 0;
/*by setting current to a blank space ABOVE the for loop, when the if statement first runs, it's comparing [paragraph characterAtIndex:i to a blank space. Once the loop runs through for the first time, the next value that current will have is characterAtIndex:0, while the if statement in the FOR loop will hold a value of characterAtIndex:1*/
char current = ' ';
for (int i=0; i< paragraph.length; i++) {
if ([paragraph characterAtIndex:i] == ' ' && (current != ' ')) {
wordCount++;
}
current = [paragraph characterAtIndex:i];
//after one iteration, current will be T and it will be comparing it to paragraph[1] which is h.
}
wordCount ++;
NSLog(#"%i", wordCount);
}
return 0;
}
I tried adding "or" statements to account for delimiters such as ";" "," and "." instead of just looking at a space. It didn't work...any idea what I can do, logically speaking, to account for anything that isn't a letter (but preferably just limiting it to these four delimiters - . , ; and space.
A standard way to solve these types of problems is to build a finite state machine, your code isn't quite one but its close.
Instead of thinking about comparing the previous and current characters think in terms of states - you can start with just two, in a word and not in a word.
Now for each state you consider what the current character implies in terms of actions and changes to the state. For example, if the state is not in a word and the current character is a letter then the action is increment word count and the next state is in a word.
In (Objective-)C you can build a simple finite state machine using an enum to give the states names and a case statement inside a loop. In pseudo-code this is something like:
typedef enum { NotInWord, InWord } State;
State currentState = NotInWord;
NSUInteger wordCount = 0;
for currentChar in sourceString
case currentState of
NotInWord:
if currentChar is word start character -- e.g. a letter
then
increment wordCount;
currentState = InWord;
InWord:
if currentChar is not a word character -- e.g. a letter
then
currentState = NotInWord;
end case
end for
The above is just a step from your original algorithm - recasting it in terms of states rather than the previous character.
Now if you want to get smarter you can add more states. For example how many words are there in "Karan's question"? Two. So you might want to allow a single apostrophe in a word. To handle that you can add a state AfterApostrophe whose logic is the same as the current InWord; and modify InWord logic to include if the current character is an apostrophe the next state is AfterApostrophe - that would allow one apostrophe in a word (or its end, which is also valid). Next you might want to consider hyphenated words, etc...
To test if a character is a particular type you have two easy choices:
If this is just an exercise and you are happy to stick with the ASCII range of characters there are functions such as isdigit(), isletter() etc.
If you want to handle full Unicode you can use the NSCharacterSet type with its pre-defined sets for letters, digits, etc.
See the documentation for both of the above choices.
HTH
I don't understand, You should be able to add or statements....
int main(void) {
char paragraph[] = "This is a test paragraph,EXTRAWORDHERE and we will be testing out a string.";
char current = ' ';
int i;
int wordCount = 0;
for (i = 0; i < sizeof(paragraph); i++){
if ((paragraph[i] == 32 || paragraph[i] == 44) && !(current == 32 || current == 44)){ //32 = ascii for space, 44 for comma
wordCount++;
}
current = paragraph[i];
}
wordCount++;
printf("%d\n",wordCount);
return 0;
}
I suppose it would be better to change the comparison of current from a not equal to into an equal to. Hopefully that helps.

How to rewrite token stream more than once using ANTLR4

I implement simple preprocessor using the great ANTLR4 library. The program itself runs in several iterations - in each iteration the future output is modified slightly.
Currently I use TokenStreamRewriter and its methods delete, insertAfter, replace and getText.
Unfortunately I can't manage to rewrite tokens that was rewritten before (got IllegalArgumentException). This is not a bug but according to the source code multiple replacement can't be achieved in any way.
I suppose that a proper solution exists as this appears to be a common problem. Could anyone please hint me? I'd rather use some existing and tested solution than reimplement the rewriter itself.
Maybe the rewriter isn't the right tool to use.
Thanks for help
Good evening
Now a dynamic code for the same problem. First you must have made visible in your listener class the Token stream and the rewriter
Here is the code of the constructor of my VB6Mylistener class
class VB6MYListener : public VB6ParserListener {
public: string FicName;
int numero ; // numero de la regle
wstring BaseFile;
CommonTokenStream* TOK ;
TokenStreamRewriter* Rewriter ;
// Fonctions pour la traduction avec le listener void functions
created by ANTLR4 ( contextes )
VB6MYListener( CommonTokenStream* tok , wstring baseFile, TokenStreamRewriter* rewriter , string Name)
{
TOK = tok; // Flux de tokens
BaseFile = baseFile; // Fichier entree en VB6
Rewriter = rewriter;
FicName = Name; // Nom du fichier courant pour suivi
}
Here in a context i cross with the listener. The Tokenstream is TOK visible by all the functions void
std::string retourchaine;
std::vector<std::string> TAB{};
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop>getTokenIndex(); i++)
{
TAB.push_back(TOK->get(i)->getText()); // HERE TOK
}
for (auto element : TAB)
{
if (element == "=") { element = ":="; }
if (element != "As" && element != "Private" && element != "Public")
{
std::cout << element << std::endl;
retourchaine += element ; // retour de la chaine au contexte
}
}
retourchaine = retourchaine + " ;";
Rewriter->replace(ctx->start, ctx->stop, retourchaine );
`
A workaround I am using because I need to make a replacement in the token and the Tokenrewriter does not make the job correctly when you have multiple replacements in one context.
In each context I can make the stream of tokens visible and I use an array to copy all the tokens in the context and create a string with the replacement and after that, I use Rewriter->replace( ctx->start , ctx->stop , tokentext ) ;
Some code here for a context:
string TAB[265];
string tokentext = "";
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop->getTokenIndex(); i++)
{
TAB[i] = TOK->get(i)->getText();
// if (TOK->get(i)->getText() != "As" && TOK->get(i)->getText() != "Private" && TOK->get(i)->getText() != "Public")
//if (TOK->get(i)->getText() == "=")
//{
if (TAB[i] == "=") { TAB[i] = ":="; }
// if (TAB[i] == "=") { TAB[i] = "="; } // autres changements
if (TAB[i] != "As" && TAB[i] != "Private" && TAB[i] != "Public") { tokentext += TAB[i]; }
cout << "nombre de tokens du contexte" << endl;
cout << i << endl;
}
tokentext = tokentext + " ;";
cout << tokentext << endl;
Rewriter->replace(ctx->start, ctx->stop, tokentext);
It's a a basic code I use to make the job robust. Hope this will be useful.
i think that rewriting the token stream is not a good idea, because you can't
treat the general case of a tree. The TokenStreamRewriter tool of ANTLR is usefulness. If you use a listener , you can't change the AST tree and the contexts created by ANTLR. you must use a Bufferedwriter to do the job for rewriting the context you change locally in the final file of your translation.
Thanks to Ewa Hechsman and her program on github on a transpiler from Pascal to Python.
I think it'a real solution for a professional project.
So i agree with Ira Baxter. we need a rewriting tree

Flush stdin using fgets

Trying to make a registration page through the console.
I need several inputs for it, and I'm using fgets, so I need to flush stdin.
Lots of similar questions on Stack Overflow redirected here: http://c-faq.com/stdio/stdinflush2.html.
I got the code below using that link. However, this doesn't actually work. It says Username:, and then when I type in a username, and press enter, it just goes to a new, empty line in console where I can type in more.
Why is this happening?
How can I fix it?
EDIT: Added code
NSLog(#"Do you have an account already?(1 for Yes, 0 for no)");
fgets(cnumb1, 2, stdin);
int c;
while((c = getchar()) != '\n' && c != EOF);
size_t length = strlen(cnumb1);
if (cnumb1 [length-1] == '\n'){ // In case that the input string has 1 character plus '\n'
cnumb1 [length-1] = '\0';} // Plus '\0', the '\n' isn't added and the if condition is false.
NSString* string = [NSString stringWithUTF8String: cnumb1];
if (string == 0) {
while(numb4 == 1) {
numb3 = 1;
while( numb3 == 1){
NSLog(#"Username:");
fgets(usercheck1, 13, stdin);
int c2;
while((c2 = getchar()) != '\n' && c2 != EOF);
size_t length1 = strlen(usercheck1);
if (usercheck1 [length1-1] == '\n'){ // In case that the input string has 12 characters plus '\n'
usercheck1 [length1-1] = '\0';} // Plus '\0', the '\n' isn't added and the if condition is false.
Completely rewrote my answer, looks like I didn't understand the problem well enough.
The line that is supposed to empty the input buffer will not get anything until the user presses return again - unless the user enters more characters than the input buffer can hold.
You should first check the length of string read by fgets and if the last character (before the \0) is a \n, don't try to read more characters. Otherwise empty the input buffer like you did.

How to prevent vb.net from differentiating à to a

We know a tolower function will turn all A to a
How to turn all à to a.
The purpose is I am creating ids for databases and id need to be unique. Sometimes the same stores are written as à in one place and as a on other places. This will create duplicate id problem.
So I need a function that will turn all à and all of it's variation into a. The same way ě should become e.
Basically I would use utf8_unicode collation on my databases. Letters that count as the same letter under that collation should map to the same character under this function.
I need to make sure that all other east asian characers are not affected in anyway.
How can I do so?
static string RemoveDiacritics(string stIn)
{
string stFormD = stIn.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for (int ich = 0; ich < stFormD.Length; ich++)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
if (uc != UnicodeCategory.NonSpacingMark)
{
sb.Append(stFormD[ich]);
}
}
return (sb.ToString().Normalize(NormalizationForm.FormC));
}