357mag 2 Posted April 1, 2023 Okay I figured I would try some Windows programming so I wanted to write a simple program that makes an array with 3 elements in it. It uses a for loop to populate the array with the values 0, 1, and 2. Then what I wanted to do was to click the button and you could see the numbers 0, 1, and 2 separated by a space. But it's not working as intended. It compiles fine. But when I run it and press the button nothing happens. There are no numbers that are seen in the Edit box. Beats me what is wrong. It's hard to be a beginner to GUI programming. Here is my code: void __fastcall TForm1::Button1Click(TObject *Sender) { int numbers[3]; int t; for(t = 0; t < 3; t++) numbers[t] = t; for(t = 0; t < 3; t++) Edit1 -> Text = numbers[t] + " "; } Share this post Link to post
Remy Lebeau 1397 Posted April 1, 2023 (edited) 1 hour ago, 357mag said: But it's not working as intended. It compiles fine. But when I run it and press the button nothing happens. Not true. Something DOES happen. It is just not what you are expecting to happen. Quote There are no numbers that are seen in the Edit box. Beats me what is wrong. Your code has two logic flaws: 1) You are inadvertently invoking pointer arithmetic rather than string concatenation. " " is a string literal of type 'const char[2]', where its 1st element is a space character, and its 2nd element is a null terminator, eg: const char literal[2] = {' ', '\0'}; So, in the expression: numbers[t] + " " You are adding a char[] array to an integer, so the compiler will implicitly decay the char[] array into a char* pointer to its first element, and then the integer will advance that pointer by the number of characters which the integer specifies. So, on the 1st loop iteration, you are effectively assigning the TEdit::Text property a char* pointer to the literal's character at index 0, ie the space character, as-if you had written the code like this: const char literal[2] = {' ', '\0'}; const char *temp = &literal[0]; temp += numbers[t]; // effectively: temp += 0, aka &literal[0] Edit1->Text = temp; Which works fine, as the resulting char* pointer being assigned to the TEdit::Text is a valid null-terminated C-string of length 1 character, so you end up with just the space character in the TEdit::Text, as expected. Then, on the 2nd loop iteration, you are effectively assigning the TEdit::Text property a char* pointer to the literal's character at index 1, ie the null terminator, eg: const char literal[2] = {' ', '\0'}; const char *temp = &literal[0]; temp += numbers[t]; // effectively: temp += 1, aka &literal[1] Edit1->Text = temp; Which also works fine, as the resulting char* pointer being assigned to the TEdit::Text is a valid null-terminated C-string of length 0 characters, so you end up clearing the TEdit::Text. However, on the 3rd loop iteration, you are effectively assigning the TEdit::Text property a char* pointer to the literal's character at index 2, which doesn't exist, so you end up invoking undefined behavior by reading into invalid memory. const char literal[2] = {' ', '\0'}; const char *temp = &literal[0]; temp += numbers[t]; // effectively: temp += 2, aka &literal[2] Edit1->Text = temp; // UB, literal[2] doesn't exist !!! To fix that, you need to explicitly convert each number into a String object yourself before adding " " to it. The compiler will NOT do that conversion automatically for you. You can use the RTL's IntToStr() function, or the String's class constructor that takes an integer as a parameter. 2) your final loop is attempting to display only one element from the numbers array on each iteration. You are completely replacing the content of TEdit::Text with a new string value. As such, by the time that loop is finished, only the last element in the numbers array would be visible in the TEdit. To fix that, you would need to change this: Edit1 -> Text = ...; To this instead: Edit1 -> Text = Edit1 -> Text + ...; So that each loop iteration is appending to the current TEdit::Text value, rather than replacing it. With all of that said, try this instead: void __fastcall TForm1::Button1Click(TObject *Sender) { int numbers[3]; int t; for(t = 0; t < 3; ++t) { numbers[t] = t; } Edit1->Clear(); for(t = 0; t < 3; ++t) { Edit1->Text = Edit1->Text + IntToStr(numbers[t]) + " "; // or: // Edit1->Text = Edit1->Text + String(numbers[t]) + " "; } } That being said, I would suggest another change - don't assign the TEdit::Text on each loop iteration. Use a local String variable first, and then assign that to the TEdit::Text after the loop is finished. Don't make the UI do more work than it actually needs to, eg: void __fastcall TForm1::Button1Click(TObject *Sender) { int numbers[3]; int t; for(t = 0; t < 3; ++t) { numbers[t] = t; } String str; for(t = 0; t < 3; ++t) { str += (IntToStr(numbers[t]) + " "); // or: // str += (String(numbers[t]) + " "); // alternatively: // str.cat_sprintf(_D("%d "), numbers[t]); } Edit1->Text = str; } Edited April 1, 2023 by Remy Lebeau Share this post Link to post
DelphiUdIT 176 Posted April 1, 2023 (edited) May be you means: P.S.: .... I didn't see the Remy post ... void __fastcall TForm1::Button1Click(TObject *Sender) { int numbers[3]; int t; Edit1->Text = ""; //Clear the Edit1 for(t = 0; t < 3; t++) numbers[t] = t; for(t = 0; t < 3; t++) Edit1->Text = Edit1 -> Text + IntToStr(numbers[t]) + " "; //The new text is "added" to the Edit1 content (the number must be transformed into text) } Edited April 1, 2023 by DelphiUdIT Share this post Link to post
357mag 2 Posted April 1, 2023 This is all that was needed: for(t = 0; t < 3; t++) Edit1 -> Text = Edit1 -> Text + numbers[t] + " "; Share this post Link to post
357mag 2 Posted April 1, 2023 My program works now but I get a long, red bar at the bottom of of the IDE. First it's blue and then it turns red. Thread Start Thread ID 7548 Process Project1.exe (13868) It's under the Event Log title. Don't know what that is all about. Share this post Link to post
Remy Lebeau 1397 Posted April 1, 2023 24 minutes ago, 357mag said: My program works now but I get a long, red bar at the bottom of of the IDE. First it's blue and then it turns red. Thread Start Thread ID 7548 Process Project1.exe (13868) It's under the Event Log title. I have no idea what you are referring to. Please provide a screenshot. Share this post Link to post
357mag 2 Posted April 2, 2023 I can't provide a screenshot at the moment. Today has been experimentation day. Working with a couple of different IDE's and I think I'm leaning in the direction of using Visual C#. If I do any more experimentation with Builder I will provide a screenshot. Share this post Link to post