Edit an existing file in C++ - c++

I have preferences file for my application in Qt.
Whenever I launch the application it loads the file & depending the contents creates the widgets accordingly. I have given some customisation option for the user. Now when my application is closed I am checking whether the preferences are changed. If yes then I am opening the preferences file again & then just adding everything again in it. I am not creating a temporary file, I am directly editing the file. Is this method an efficient one? or am I doing it wrong? because I found these threads:
1. What is the best way to edit the middle of an existing flat file?
http://qt-project.org/forums/viewthread/25924/
Should use I binary file? Currently I am using ASCII file.
Thanks.
UPDATE: In the stackoverflow link above the correct answer has
If you're stuck using flat, then you're stuck using the old fashioned
way of updating them
I meant to ask whether the method I am using is old fashioned & is there a better method used nowadays? & what does flat file mean?

Don't try to edit the file. Rewrite the whole thing
Rewrite by using a temporary file. i.e. write the current state of preferences into temp file. And then move/rename the file to your actual preference file after making sure the temp file has been written successfully. This helps in case there is a crash when you rewriting the file. If you rewrite it directly, you will be left with neither the old one nor a good new one. In case you do it through a temp file, then do it this way ensures that in case of a crash, you atleast have a good preferences file(though it contains the old preferences).
Text/Binary doesn't make much difference unless it's a really huge file. Text will help to hand edit it if required.

That's a perfectly fine way of doing it. Since you already seem to have all of the preferences loaded into memory and you have edited them there, you don't need to bother with a temporary file (unless you want to ensure safety if your program fails during writing). Just write all of the preferences back into the original file.
Whether you choose a binary file or text file is up to you. Preferences tend to be text files because they have the added benefit of being human readable with just a text editor, rather than some specialised software for viewing them. A binary file may, however, have slightly better performance due to simpler decoding.

Related

Methods for opening a specific file inside the project WITHOUT knowing what the working directory will be

I've had trouble with this issue across many languages, most recently with C++.
The Issue Exemplified
Let's say we're working with C++ and have the following file structure for a project:
("Project" main folder with three [modules, data, etc] subfolders)
Now say:
Our maincode.cpp is in the Project folder
moduleA.cpp is in modules folder
data.txt is in data folder
moduleA.cpp wants to read data.txt
So the way I'd currently do it would be to assume maincode.cpp gets compiled & executed inside the Project folder, and so hardcode the path data/data.txt in moduleA.cpp to do the reading (say I used fstream fs("data/data.txt") to do so).
But what if the code was, for some reason, executed inside etc folder?
Is there a way around this?
The Questions
Is this a valid question? Or am I missing something with the wd (working directory) concept fundamentals?
Are there any methods for working around absolute paths so as to solve this issue in C++?
Are there any universal methods for doing the same with any language?
If there are no reasonable methods, how would you approach this issue?
Please leave a comment if I missed any important details with the problem's illustration!
At some point the program has to make an assumption where the file(s) are. Either by getting it from user input or a relative path with the presumed filename. As already said in the comments, C++ recently got std::filesystem added in C++17 which can help you making cross-platform code that interacts with the hosts' filesystem.
That being said, every program, big or small, has to make certain assumptions at some point, deleting or moving certain files is problematic for any program in case the program requires them to be at a certain location under a certain name. This is not solvable other than presenting the user with an error message etc.
As #Hatted Rooster said, it's not generally solvable for some arbitrary file without making some assumptions, however there are frameworks that allow you to "store" some files in the resources embedded into the executable (or otherwise). Those frameworks would usually allow your to handle such files in a opaque way, without the need to rely on a current working dir or relative paths.
For example, see the Qt Resource System.
Your program can deduce the path from argv[0] in the main call, if you know that it is always relative to your executable or you use an absolute path like "C:\myProgram\data\data.txt".
The second approach works in every language.

.How do you create a new file in Ocaml and where does it store it?

I can't seem to find the answer, how do you create a new file in Ocaml? Do you edit your file in the terminal? Where does the source code appear?
I think you're asking how to write code in OCaml, i.e., how to create an OCaml source file. (This isn't completely clear. You could be asking how to write OCaml code that creates a file.)
The details of creating OCaml source depend on your development environment, not on the language itself. So there is no one answer.
The general answer is that you can use any tool you like that knows how to create a text file. If you like working from the command line (as I do) you can work in a terminal environment and run some kind of vintage text editor from the last millennium (as I do). If you like a GUI environment, you can run some kind of "programmer's editor" from the current millennium, or really any kind of editor that creates basic utf-8 files (or even ASCII files).
Generally the editor will have to be told where to store the files that you edit. You would probably want to make some kind of folder for the project and make sure you store the text files in there.
I hope this helps! If you have any programmers nearby, they can probably get you started a lot faster than asking on StackOverflow.

Monitor file after cut and paste (Windows Shell Extension?)

I'm currently in the idea phase for a small application that requires keeping track of specific, user chosen files.
I want the system to be intuitive, such that a user can change the file name, directory name, or move the file to a new location, and the application would still be able to keep track of the file.
Now, I know that I can monitor directories already, for the majority of these kinds of changes, with windows system calls.
The problem I'd have is finding if/when a file is cut, copied, or pasted somewhere. I've read a little about shell extensions, but they have actually rather confused me (since I haven't had the time to actually read good and long about them yet). Is there a way I could monitor a file for being cut/pasted/copied, so that my application could continue to track the file in it's new location? Would I have to do this through a shell extension?
You can use shortcut objects to track files even if they are renamed or moved.

How Can A .dll File Read a .txt File?

I would like my Browser Helper Object which is simply a .dll, to be able to read a text file. I have tried using a pointer to a FILE, as well as ifstream in("file name goes here"). Before implementing these two methods of reading files into the BHO, I tested them individually, and made sure each example dealt with similar data types and locations. Both of them worked without a problem, yet testing the BHO reveals that the file cant even be opened. I have searched google for an alternative method, and after exhausting all other options, I'm hoping that someone would be able to provide me with some guidance/resource. Anything is appreciated; I will keep trying to find a solution and will post what I can in the event that someone else may have the same problem.
Are you providing an absolute path to the file? If you're just using a relative path you may not be in the same working directory while running IE.
I think you might be a victim of the IE protected mode.
http://www.codeproject.com/KB/vista-security/PMSurvivalGuide.aspx
Under protected mode your addin might not have access to registry and file system as you might like.

Opening a File with different text editors

Apparently this supposed to be possible. For example opening and operating on a file with NOTEPAD, or HxD. But aren't they all text files...how would one specify which text editor to open the file and operate on the file with using the WINDOWS API. It is certainly not in "CreateFile".
Hopefully I'm understanding your question... The easiest way to do this is to launch the desired editor and pass the filename as an argument, rather than "invoking" the file (which will launch the default program associated with the file type).
For example, notepad.exe mytextfile.txt or gvim.exe mytextfile.txt.
If the editor is not on your %PATH%, you'll need to use a full path file name.
What are you trying to do, exactly? You could:
Maintain a list of editors that you expect to be installed and have entries for in the system's PATH (bad idea)
Have an editor/editors that you want to use, query the Windows registry to find the installation path of the editors (using RegGetValue), and launch the editor with CreateProcess) (a little better idea)
Query the registry to get the default editor for a given file type and then launch that editor using CreateProcess. (best idea)
But it all depends on what your goal is really.
Edit based on requirements
So, just so we're on the same page, from C++, you want to:
Take a command line parameter to your C++ application (filename)
Open that file in an arbitrary editor
Detect when the user has made changes to that file
Operate on the file contents
Is that correct?
If so, you could:
Use Boost libs to compute a CRC for the current data in the file
Launch an editor using one of the methods I initially described
Stick in a tight loop and sleep so you don't chew up resources while the initially computed CRC matches one calculated every iteration of the loop
Of course, there are all kinds of issues that you'd have to deal with (that's just a super simple way of describing the algorithm I might use), such as:
What happens if the user doesn't change the file?
What happens if the file isn't found?
I'm sure that there are a number of different methods of doing this, but this is the easiest method that I can think of at the moment (while still being able to be fairly certain of the changes).
Disclaimer: I haven't implemented something like this, so I might be completely off base ;)
Are you looking for the ShellExecute() or ShellExecuteEx() APIs on Windows? They'll launch whatever program is registered for a file (generally based on the filename extention).