I would like to open a file "my_query.sql" and read the entire text of that file into some macro variable x.
Clearly, I should start with something like:
file open myfile using my_query.sql
But my problem is that file read myfile x isn't quite right as that just reads the first line...
My initial ideas:
Perhaps there is a way to open it in binary and read the whole thing in with a single command?
Or do I have to do some hacked up, read the file line by line and concatenate the strings together?
My preferred solution is the "hacked up, read the file line by line and concatenate" solution.
I can also understand why the solution may seem hacked up, especially for somebody coming from a programming language. For example, this approach might even seem silly next to something like a BufferedReader in Java, but I digress...
You only get the first line of the file when you execute file read myfile x because, according to the documentation at help file:
"The file is positioned at the top (tof), so the first file read reads at the beginning of the file."
This is actually a convenience if you are writing to a file with file write because you won't have to embed newline characters in the string you wish to write - each call to file write will write a new line.
Now, there is a very simple loop construct that allows us to read line by line and store the contents into the macro.
So, if I had a .sql file at /path/to/my/file/ titled SqlScript.sql with the following contents:
SELECT *
FROM MyTable
WHERE Condition
Then the solution becomes something along the lines of:
clear *
file open myfile using "/path/to/my/file/SqlScript.sql", read
file read myfile line
local x "`line'"
while r(eof) == 0 {
file read myfile line
local x "`x'" " " "`line'"
}
file close myfile
di "`x'"
and the result:
SELECT * FROM MyTable WHERE Condition
Here, I used r(eof) to condition my while loop. This is an end of file marker which evaluates to 1 when file read reaches the end of the file.
Here's something that may help you open the file in binary and read it into a local macro.
The good news is, this appears to read the entire text file into the macro in one read.
clear *
file open myfile using "SqlScript.sql", read binary
file read myfile %100s line
local x "`line'"
file close myfile
di "`line'"
The bad news it, it (as written) reads 100 characters - it doesn't know where to stop. I think that if you know what signifies end-of-text-file on your operating system, you could search for that character and substring everything up to it. But dealing this this is beyond me at the moment. And you'll want to replace the newlines with spaces.
If this can be made to work for you I'd like to see the solution.
Related
I have a file containing A heading followed by the encrypted data. I need to ignore the 1st line (heading ) and read the rest of the file and then decrypt. I am doing this in C++. How do i go about it. I have tried getLine, but doesnt seem to work
I would like to read a text file in C++ in following manner:
Ignore the entire first line as it is simply meant as an introduction.
Only read the following lines from a specific position.
That starting position for reading is a fixed one and remains the same for every line; however, the numbers after that may be of variable length. I need to save all of these numbers from line 2 to line n into an Array.
At the moment I can read a regular 2D Array with getline.
How can I work around these things?
An example for a line I want to read could be:
Person1: 25 988.3 0.0023 7
To set the file to a position, use std::ifstream::seekg().
To set the file to the beginning of a line, you must read and count the line endings. Many text files have variable length text lines.
How can I work around these things?
You can't, unless you can ensure that all of the data lines after the first line are all the same length.
If you can't ensure that, then all you can do is read through all of the preceding lines.
An alternative I have employed in the past is to generate an 'index' of line start positions in a secondary file in binary format (so that I CAN jump directly to the right place in that file), and use that to jump to the right place in the text file. Of course that means that you need to regenerate that index file every time you replace/amend the data file.
I have a GEDCOM file, which I am supplying to my program, my program checks the content of GEDCOM file against a set of functions.
If the contents of file, fail to match the requirements of function, it should throw an error along with the line number on the GEDCOM file where error exists.
I would also like to mention that I have tried using macros like LINE, FILE but they are printing the contents of source code like line of source code and file name of source code.
Thanks in advance
If you are reading the file one line at a time you can keep a counter of the number of lines you have read from the file.
If you already have the whole file in one big buffer you can scan the number of newline or return characters.
If you provide a MCV example demonstrating your code reading in the file I can maybe help more.
I am trying to read a file using ifstream. And while reading (line-by-line), it encrypts each line and has to replace the original line with the new encrypted line. I have so far been able to read from the file but replacing the current line ( current line = line last read ) is what I can't figure out how to do. My question it: How do I replace a line in a file which I last read, using getline(...)?
The problem is you can't delete a specific data in a file; you have to write it from the beginning.
But with f_seek and r+ you may insert some data whatever you want.
I can't understand the description of the "a" and "a+" option in the C fopen api documentation. The option in "a+" is append and update. What is the meaning of the word update here?
Here is what the man pages (man fopen) say:
a
Open for appending (writing at end of file). The file is created if it
does not exist. The stream is positioned at the end of the file.
a+
Open for reading and appending (writing at end of file). The file is
created if it does not exist. The initial file position for reading is
at the beginning of the file, but output is always appended to the end
of the file.
Which means:
for a+:
pointer initially is at the start of the file ( for reading ) but when a write operation is attempted it is moved to the end of the file.
Yes, there is an important difference:
a: append data in a file, it can update the file writing some data at the end;
a+ : append data in a file and update it, which means it can write at the end and also is able to read the file.
In a pratical situation of only writing a log both are suitable, but if you also need to read something in the file (using the already opened file in append mode) you need to use "a+".