Greetings from Greece, this is my first post!

I'm having some minor trouble with an application I've been working on the past week. So if you could please shed some light into this.
Thank you.
The problem I'm having is that when the user is trying to save a file something goes wrong. Let me explain.

Once the program starts a new file is created called "unsaved.txt", its name taken from a main.h global char* variable.
If the program exits, the "unsaved.txt" file is automatically deleted, if ofcourse it's still there.

Now what the 'save' function does is change the file name so that it is not deleted when the user exits.

The problem here is that although I manage to rename the file name from "unsaved.txt" to whatever the user enters, the global char* variable (fileName) won't change and remain "unsaved.txt" so the next time I try to write something new into this file it will still create a new "unsaved.txt".

Take a look at this and please let me know if I'm doing anything wrong.

The 'saveFunction' :

if (!fileNameEdit->Text.IsEmpty()) {
                String newFileName = fileNameEdit->Text + ".txt";
                rename( "unsaved.txt", newFileName.c_str() );
                fileName = newFileName.c_str();
                this->Close();
        }
        else {
                Application->MessageBox("Please enter a file name.", MB_OK | MB_ICONEXCLAMATION);
        }
WaltP commented: First post and you used CODE Tags, and actually explained the problem! Fantastic!!! +9

Recommended Answers

All 10 Replies

The problem here is that although I manage to rename the file name from "unsaved.txt" to whatever the user enters, the global char* variable (fileName) won't change and remain "unsaved.txt" so the next time I try to write something new into this file it will still create a new "unsaved.txt".

You cannot change the contents of a constant string, which I assume is your problem. If you have: char *fname = "unsaved.txt"; it's a string constant and cannot be modified.

On the other hand, if you have char fname[] = "unsaved.txt"; you can change the name. But if you change it to "theRealFileName.txt" you have another problem. You just moved 20 characters into a string defined as 12 characters so you overwrote unknown memory -- a very bad thing.

To fix that, define the string as char fname[100] = "unsaved.txt"; and you'll have 99 characters to play with.

Right, but if someone enters a name shorter than "unsaved.txt" wouldn't that leave some extra characters at the end of the array?

For example : unsaved.txt to new.txt
[0] = "u"
[1] = "n"
[2] = "s"
[3] = "a"
[4] = "v"
[5] = "e"
[6] = "d"
[7] = "."
[8] = "t"
[9] = "x"
[10] = "t"
[11] = "\0"
would become
[0] = "n"
[1] = "e"
[2] = "w"
[3] = "."
[4] = "t"
[5] = "x"
[6] = "t"
[7] = "\0"
[8] = "t"
[9] = "x"
[10] = "t"
[11] = "\0"

No?

Yes. But the '\0' in 7 is the end of the string so the last few characters are essentially invisible.

and you do not want to rely on someone typing less than 12 characters.

Alrightie then. Thanks for your input!

Alrightie then. Thanks for your input!

But I seem to be facing a different problem now. Is there a way to convert a String variable to char []? I can't get it to work, the application crashes at runtime once I try to save the file.

if (!fileNameEdit->Text.IsEmpty()) {
                String newFileName = fileNameEdit->Text + ".txt";
                rename( "unsaved.txt", newFileName.c_str() );
                for (int i = 0; i < newFileName.Length(); i++) {
                        fileName[i] = newFileName[i];
                }
                this->Close();
        }

I cannot try to input the String directly into the fileName variable because then I'm getting a compiler error saying "LValue required."

How is the fileName actually declared?

How is the fileName actually declared?

char fileName[100] = "unsaved.txt"

char fileName[100] = "unsaved.txt"

OK, what you have there seems like the right way of doing it, as long as newFileName.Length() does not exceed the buffer size. Just a suggestion, to simplify the code a little bit;

// also fileName is of type String ...
String fileName = "unsaved.txt";

// and ...
String newFileName = fileNameEdit->Text + ".txt";
rename( "unsaved.txt", newFileName.c_str() );
fileName = newFileName;

Regarding the crash (what kind of crash actually?), have you run the program in the debugger to see at which line it crashes?


[EDIT] Hmm, the post I'm replying to appears below this one.

// also fileName is of type String ...
String fileName = "unsaved.txt";

// and ...
String newFileName = fileNameEdit->Text + ".txt";
rename( "unsaved.txt", newFileName.c_str() );
fileName = newFileName;

Regarding the crash (what kind of crash actually?), have you run the program in the debugger to see at which line it crashes?

I've run the debugger. The program crashes inside the for loop, where I try to copy newFileName into fileName.
fileName appears to be "unsaved.txt\0\0\0\0\0\0\0\0" until 100 chars and newFilename is what I entered...

I'm not sure about what kind of crash it is or how to determine that.
But I get an error saying "Project blabla raised exception class EAccessViolation with message 'Access violation at address ### in module rtl60.bpl.' Read of address ###."

Is there a way to convert a String variable to char []?

I pretty much missed the fact that this is about Borland's String class.
In that case the looping over the string and copying it byte by byte using the [] operator won't work.

If you want to stick with char fileName[100] then you can use e.g. strcpy()/strncpy() together with the String's c_str() method.

However, wouldn't it be easiest to change the type of fileName to String , so you could do a simple assignment, instead of hassling with C-style strings.

PS. The order of the posts in this thread is odd ... let's see where this one lands.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.