Turbo C++ : while(fin) vs while(!fin.eof()) - while-loop

I was told that I should be using while(fin) instead of while(!fin.eof()) when reading a file.
What exactly is the difference?
Edit: I do know that while(fin) actually checks the stream object and that when it becomes NULL, the loop breaks and it covers eof and fail flags.
But my course teacher says that fin.eof() is better so I need to understand the fundamental operation that's going on here.
Which one is the right practice?
Note: This is not a duplicate, I need assistance in Turbo C++ and with binary files.
I'm basically trying to read a file using a class object.

First of all I am assuming fin is your fstream object. In which case your teacher would not have told you to use while(fin.eof()) for reading from file. She would have told to use while(!fin.eof()).
Let me explain. eof() is a member of the fstream class which returns a true or false value depending on whether the End Of File (eof) of the file you are reading has been reached. Thus while eof() function returns 0 it means the end of file has not been reached and loop continues to execute, but when eof() returns 1 the end of the file has been reached and the loop exits.
while(fin) loop is entered because fin actually returns the value of an error flag variable inside the class object fin whose value is set to 0 when any function like read or write or open fails. Thus the loop works as long as the read function inside the loop works.
Personally I would not suggest either of them.
I would suggest
//assume a class abc.
abc ob;
While(fin.read((char*)&ob, sizeof(ob)))
{}
Or
While(fin.getline(parameters))
{}
This loop reads the file record inside the loop condition and if nothing was read due to the end of file being reached, the loop is exited.
The problem with while(!fin.eof()) is that it returns 1 if the end of file has been reached. End of file is actually a character that is put at the end of the file. So when the read function inside the loop reads this character and sets a variable eof to 1. All the function actually does is return this value.
Thus works fine when you are reading lines in words but when you are reading successive records of a class from a file, this method will fail.
Consider
clas abc
{}a;
Fstream fin("file");
While(!fin.eof())
{
fin.read((char*)&a,sizeof(a));
a.display(); // display is a member function which displays the info }
Thus displays the last record twice. This is because the end of file character is the character after the last byte of the last record. When the last is read the file pointer is at the eof byte but hasn't read it yet. So it will enter the loop again but this time the eof char is read but the read function fails. The values already in the variable a, that is the previous records will be displayed again.

One good method is to do something like this:
while ( instream.read(...) && !instream.eof() ) { //Reading a binary file
Statement1;
Statement2;
}
or in case of a text file:
while ( (ch = instream.get()) && !instream.eof() ) { //To read a single character
Statement1;
Statement2;
}
Here, the object is being read within the while loop's condition statement and then the value of eof flag is being tested.
This wouldn't result in undesired outputs.
Here we are checking the status of the actual I/O operation and the eof together. You may also check for the fail flag.
I would like to point out that according to #RetiredNinja, we may only check for the I/O operation.
That is:
while ( instream.read(...) ) { //Reading a binary file
Statement1;
Statement2;
}

A quick and easy workaround that worked for me to avoid any problems when using eof is to check for it after the first reading and not as a condition of the while loop itself. Something like this:
while (true) // no conditions
{
filein >> string; // an example reading, could be any kind of file reading instruction
if (filein.eof()) break; // break the while loop if eof was reached
// the rest of the code
}

Related

Kotlin - read only first n lines in file

Is there a method, without resolving to traditional Java-like for loops, to limit the number of lines read by BufferedReader?
Take this code for example:
bufferedReader.useLines { it }
.take(10)
.toList()
The documentation for useLines states:
Calls the [block] callback giving it a sequence of all the lines in this file and closes the reader once
* the processing is complete.
To my understanding, this means that the entire file will be read, and only then the first ten will be filtered out of the sequence. I couldn't find anything online addressing this issue except fetching only the first line.
Sequence is a lazily evaluated collection. That means only the necessary items will be processed, so if you take(10), only the first 10 lines will be processed.
The keyword in the documentation is thus:
Calls the [block] callback giving it a sequence of all the lines in
this file and closes the reader once the processing is complete.
Now useLines closes the source as soon as its block is completed, making your code incorrect. Instead, use the following:
val list : List<String> = bufferedReader
.useLines { lines: Sequence<String> ->
lines
.take(10)
.toList()
}

What does it mean "whenever sqlerror exit 9"?

What does whenever sqlerror exit 9 mean?
And does the number 9 represent anything? I was thinking maybe it's a sqlerror code but I couldn't find a sqlerror code with a number 9.
Typically exiting 0 means success and non-zero means an error. The number of the exit code refers to where the error occurred, and is programmer-defined. Perhaps your program would exit 1 if login failed, 2 if a query returned no rows where at least one was expected, etc. A wrapper program can call this one, then use the return code to see if it ran successfully or not. If not, you know where in the code it failed by the number. Used as you are dealing with, they are called magic numbers. Who knows what they mean as apparently the original developer never at least defined them in a comment. Now you know why magic numbers should be avoided. Instead, define return codes as constants with a meaningful name at the top of your program, then refer to them by that name when used. Whoever maintains the code after you will sing your praises instead of cursing your existence! In Oracle PL/SQL for instance, I'd do something like this:
...
-- Define return codes.
ERR_NOLOGIN CONSTANT INTEGER := 1;
ERR_NOROWS CONSTANT INTEGER := 2;
ERR_TOO_MANY_ROWS CONSTANT INTEGER := 3;
...
-- Then in your error handing:
WHENEVER ERROR EXIT ERR_NOLOGIN; -- No magic number makes for
-- easier to read code.
...

need to create macro in Slick-C to re-enumerate

I have a bunch of test cases in an XML file named : blah_blah_blah_blah_number
The test cases have the numbers all messed up like:
blah_3
blah_1
blah_7
....
I need to re-number them. So that the first one gets renumbered 1, the second 2.. and so on. I want to build a macro for this but I don't know how to start. I need some sort of search function that can go to the pattern I give it, and then it substitutes the number with a count that I keep in some variable. I'm not proficient at all with Slick-C, and would like to get this done quickly :\
Any help appreciated,
Ted
For a more timely answer, you might consider the SlickEdit forums on slickedit.com, but I'll try here.
I would load the file in a buffer, and create a macro along the following lines:
Create a while loop incrementing a counter
In the while loop, use search with regular expressions to find the next occurrence
When the next occurrence is found, use search_replace to replace the string found with a new string composed using the counter variable, and to repeat the previous search
When nothing is to be found any more, terminate the loop
Without testing it on an XML file, this should give you a start for your function (assuming you know how to create a macro file and load it into SE), a quick test showed it to work on a plain text file, no guarantees, however:
/* Demo for StackOverflow question 14205293 */
_command my_renumber() name_info(','VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL)
{
int not_found = 0; /* boolean to terminate loop */
int iLoop = 0; /* Counter to renumber items */
/* Use search initially; if that call doen't find an item, we're done. */
if (search('blah_:i', 'R') != 0)
{
not_found = 1;
}
while (!not_found)
{
if (search_replace('blah_' :+ iLoop, 'R') == STRING_NOT_FOUND_RC)
{
not_found = 1;
}
iLoop++;
}
}

AutoHotKey Global Variable that can be accessed and modified by different macros?

I've seen a similar topic on sof but its solution did not help me. This is ticking my mind and basically all i want is to have some method of accessing and modifying a value that will maintain its last changed state through out my macros in my single .ahk file.
See example below ,
~Home::Suspend
XButton1::
tog()
return
LButton::
shot()
return
var := "1"
tog(){
var *= -1
}
shot(){
If (var = "1") {
Loop, 1 {
Send {k}
Sleep 65
Send {WheelDown}
Sleep 100
Send {WheelUP}
Sleep 10
}
} Else {
Send {k}
}
}
I am aware that the above is incorrect, and i tried to use"global" in my functions but i just couldn't get my desired effect.
Using the "global" should work. Something like:
shot(){
global var
If (var = "1") {
That points the 'var' variable in the shot() function to the existing 'var' variable defined outside the function.
I had the same issue and after some trial and error I found my mistake which is the same as in the provided code:
The correct way to declare a global is before other functions
var := "1"
XButton1::
; code...
return
The code in the OPs script will hit the return first and never declare the variable
XButton1::
; code...
return ; Returns Here
var := "1" ; Incorrect Will Not Be Declared
I just wanted to provide this as an answer because while I did see this information in one of the comments, I didn't see it until after I'd already spent an additional hour figuring it out myself. As this is the answer I needed, having it as an actual prominent answer may help someone else save time.
What I did, especially since I sometimes have multiple scripts running that need to access the same variable, is to place the var in a .ini file. I also use this to preserve the variable value after a restart. The solution is somewhat slower since the data is saved to the hard disk / SSD, but it works beautifully.
Example of writing the value "S" to variable "State" in group "Finish"
IniWrite, S, C:\2Podcasts\FinishOptions.ini, Finish, State
In an other script (other AutoHotKey instance), I read the value and assign it to the variable "FinishOption".
IniRead, FinishOption, C:\2Podcasts\FinishOptions.ini, Finish, State
If you want to toggle values (True/False), you could use this. This will do an IF on the current value of the variable AND set the variable to the opposite value.
If (MyLoop := !MyLoop) ; Toggle the variable "MyLoop" True/False
{
Do something
}
Else
{
Do something else
}
return

Specifying variable range in Verilog using for loop

I am trying to write this code:
for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
begin : loop_inst
if (i < 3)
begin
if (changed[i] & !done_q[i])
begin
writedata[3-i] = en[i];
writedata[2-i:0] = readdata[2-i:0];
writedata[15:4-i] = readdata[15:4-i];
end
end
else
...
Basically, the location of the bit I am trying to write to (en) changes depending on which address I am talking to, depending on i. This code is not synthesizable because i is not a constant.
Is there any other workaround to this? The only workaround I know is writing out those three statements CONST times. I am hoping I DON'T have to do that in the end. Is there any other solution?
It looks like you're trying to copy readdata to writedata all the time, but fill in the LSBs with en if certain special case conditions are met. I'm also going to assume that the for loop you have is in an always block, and that you're intending to build combo logic.
The for loop as you've it written doesn't make much sense to me from a hardware perspective. A for loop is used for building arrays of logic, and as you've
written it you'll have at least 3 logic cones trying to set values on the entire writedata bus. (If it generates anything at all, it'll be some weird priority structure).
That said, it's probably the range selects that your compiler is complaining about, ie the writedata[2-i:0] rather than the writedata[3-i] = en[i]; (anything with : in the part select). If you want to do something along those lines, you can use 'indexed part selects' ( +: or -:) but there are better solutions in this case.
I'd rewrite it as follows - assuming I've assumed correctly :)
always #( /*whatever*/ ) begin
// default assignment
writedata = readdata;
// overwrite some bits in writedata for special cases
for(i=0; i<3; i++) begin
if( changed[i] & !done_q[i] )
writedata[3-i] = en[i];
end
end
In this code, I'm setting writedata to readdata, and then tweaking the resulting value of writedata if the special cases are in play. The for loop is building 3 logic cones, one for each of the bits in writedata[3:1]. I'd double-check if the bit mapping is what you intend -ie, mapping en[2:0] on to writedata[1:3].