I have the following code
fin.close();
open = inName + ".xxx";
fin.open(open.c_str(),ios::binary);
fin>>noskipws;
while (fin>>_4byte[0])
{
fout<<_4byte[0];
}
I also have fout open in binary mode too.
However, this code was working perfectly, but suddenly after adding a loop before it it stopped outputting all the data, it is missing somewhere around 33~55 bytes.
I tried removing every other fin.open and fin.close to keep this one, but I keep on getting the same issue which is the output file is missing some data.
_4byte is an unsigned char array.
So I solved it, the issue was that I only had to add fin.close() after the while loop. I'm not sure why it happened. Can someone explain the reason?
Edit:
Okay that was not the issue.
After this code I had a cin, it actually stops writing when it reaches the cin if it hadn't done writing yet.
Related
(New to C++)
I have this simple code (simplified for the question):
int main()
{
string currInput;
while (getline(cin, currInput))
{
}
cout << "wont be printed" << std::flush;
return 0;
}
I have been debugging for a while and I probably miss something:
When running it and pressing ctrl+d (after some strings or right away), it does not print the string that is after the while loop. It just stop running. I thought it might be something with flushing so I added that too.
What am I missing?
PS: When running in debug, it mentions something about sighup signal.
So, with a lot of help from #manni and #rici, we found the problem.
It turns out to be a known problem in cLion.
see sending EOF to stdin in Clion IDE
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206849765-How-to-enter-EOF-Ctrl-z-in-Run-console-
https://youtrack.jetbrains.com/issue/IDEA-12514
Your error is the while loop. You should not be using a loop here. What happens is it hits this line and attempts to get input. Regardless of whether you type in anything or not, if you hit CTRL+D it will end the getline. But you have it in a while loop....so it'll hop back to the top of the loop and get another line...then another line....then another line. Welcome to your first infinite loop.
while (getline(cin, currInput))
{
}
The simplest thing would be to do just
getline(cin, currInput);
If you're starting out programming this is probably what you want to do anyway.
If you feel gutsy, read this page: http://www.cplusplus.com/reference/string/string/getline/
You'll notice that getline returns the stream you pass in. Which will evaluate to true as far the loop is concerned.
I'm writing a code in which I check a given directory for new files or directories. New in my situation is regarded to last time the code has been run in that directory. So I create a log file and then I acquire the log in a string vector. The code is the following:
ifstream Finp;
string directory;
vector <string> newfilelist;
system( ("ls -B "+directory+" > "+directory+"filelist.log").c_str() );
Finp.open( (directory+"filelist.log").c_str() );
while ( true ) {
string stmp;
Finp >> stmp;
if( Finp.eof() ) break;
newfilelist.push_back( stmp );
}
Now what's happening is the following:
1) if the log "filelist.log" already exists, everything runs smoothly
2) if the log "filelist.log" does not exist, it is correctly created but when the code opens the file and starts acquiring it, it gets stuck in a loop and the stmp string is endlessly empty (as if the file has no eof() and yet is empty!). what is intresting is the fact that if I place a random system command before opening the log everything runs smoothly!
What am I missing?
I think that, the only thing you would need to change is that nasty while(true) loop to while(file<< to_variable). This would only read data IF there is some.
The eof() is actually quite deceiving. You would guess that it is called right at the end of the file. Though true, when you try to read from the file at the >> operation the pointer in the stream will jump back before the EOF and try to read what is there.
There is quite the few threads here discussing just EOF and using that as a condition for a loop.
If the file does not exist, Finp.open() will basically fail, and checking Finp.eof() is meaningless. Before even attempt to enter a loop to read or check eof, you need to check the Finp status with Finp.good() and then proceed with reading only if this method returns true.
I was doing a graph problem in TopCoder and somehow my program kept outputting wrong answer even though I thought everything should be ok with it. I spent hours and hours looking for error in my logic and, as it turned out, the problem was lying somewhere else. Here is a snippet of code I've got a question about:
int x, y;
stringstream ssx;
stringstream ssy;
for (int i = 0; i < connects.size(); i++){
neighbours.push_back(vector<int> ());
edges_cost.push_back(vector<int> ());
ssx.str(connects[i]);
ssy.str(costs[i]);
while (ssx >> x && ssy >> y){
neighbours[i].push_back(x);
edges_cost[i].push_back(y);
}
// The problem lied here. Apparently without these 2 lines
// the program outputs wrong answer. Why?
ssx.clear();
ssy.clear();
}
As you can see in the comments I managed to solve the problem. But I can't see why do I need to clear those stringstreams. What exactly is happening if I'm not doing that?
Once you've extracted all data from the stream and attempted to read "just one more character!" (which the in-built extraction to int will try to do, to find out whether there are more digits to read), its eof bit is set.
You are re-using the stream by changing its buffer's "contents", which is fine, but you need to reset that eof bit too. That's what .clear() does.
To re-use a stringstream in general:
ss.str(""); // clears data
ss.clear(); // clears all error flag bits
(In your case you're directly replacing the buffer with your new data, later on, using .str("newText!"), instead of writing .str(""), and that's fine.)
It's confusing because a function like clear sounds like it's going to clear the data, but it doesn't.
I am currently stuck in this problem that I do not have any idea to fix. It is regarding a previous question that I have asked here before. But I will reiterate again as I found out the problem but have no idea to fix it.
My program accesses a text file that is updated constantly every millisecond 24/7. It grabs the data line by line and does comparison on each of the line. If any thing is "amiss"(defined by me), then I log that data into a .csv file. This program can be run at timed intervals(user defined).
My problem is that this program works perfectly fine on my computer but yet it doesnt on my clients computer. I have debug the program and these are my findings. Below is my code that I have reduced as much possible to ease the explanation process
int result;
char ReadLogLine[100000] = "";
FILE *readLOG_fp;
CString LogPathName;
LogPathName = Source_Folder + "\\serco.log"; //Source_Folder is found in a .ini file. Value is C:\\phython25\\xyratex\\serco_logs
readLOG_fp = fopen(LogPathName, "r+t");
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
{
Sort_Array(); // Here is a function to sort the different lines that I grabbed from the text file
Comp_State(); // I compare the lines here and store them into an array to be printed out
}
fclose(readLOG_fp);
GenerateCSV(); // This is my function to generate the csv and print everything out
In Sort_Array(), I sort the lines that I grab from the text file as they could be of different nature. For example,
CStringArray LineType_A, LineType_B, LineTypeC, LineTypeD;
if (ReadLogLine == "Example line a")
{
LineType_A.add(ReadLogLine);
}
else if (ReadLogLine == "Example line b")
{
LineType_B.add(ReadLogLine);
}
and so on.
In CompState(), I compare the different values within each LineType array to see if there are any difference. If it is different, then I store them into a seperate array to print. A simple example would be.
CStringArray PrintCSV_Array;
for (int i = 0; i <= LineType_A.GetUpperBound(); i++)
{
if (LineType_A.GetAt(0) == LineType_A.GetAt(1))
{
LineType_A.RemoveAt(0);
}
else
{
LineType_A.RemoveAt(0);
PrintCSV_Array.Add(LineType_A.GetAt(0);
}
}
This way I dont have an infinite amount of data in the array.
Now to the GenerateCSV function, it is just a normal function where I create a .csv file and print whatever I have in the PrintCSV_Array.
Now to the problem. In my client's computer, it seems to not print anything out to the CSV. I debugged the program and found out that it keeps failing here.
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
{
Sort_Array(); // Here is a function to sort the different lines that I grabbed from the text file
Comp_State(); // I compare the lines here and store them into an array to be printed out
}
fclose(readLOG_fp);
It goes into the while loop fine as I did some error checking there in the actual program. The moment it goes into the while loop it breaks out of it suggesting to me it reach EOF for some reason. When that happens, the program has no chance to go into both the Sort_Array and Comp_State functions thus giving me a blank PrintCSV_Array and nothing to print out.
Things that I have checked is that
I definitely have access to the text file.
My thoughts were because the text file is updated every
millisecond, it may have been opened by the other program to write
into it and thus not giving me access OR the text file is always in
an fopen state therefore not saving any data in for me to read. I
tested this out and the program has value added in as I see the KB's
adding up in front of my eyes.
I tried to copy the text file and paste it somewhere else for my
program to read, this way I definitely have full access to it and
once I am done with it, Ill delete it. This gave me nothing to print
aswell.
Am I right to deduce that it is always giving me EOF thus this is
having problems.
while ((result = fscanf(readLOG_fp, "%[^\n]\n", ReadLogLine)) != EOF) // Loops through the file till it reaches the end of file
If yes, How do I fix this?? What other ways can I make it read every line. I have seriously exhausted all my ideas on this problem and need some help in this.
Thanks everyone for your help.
Error is very obvious ... you might have over looked it..
You forgot to open the file.
FILE *readLOG_fp;
CString LogPathName;
LogPathName = Source_Folder + "\\serco.log";
readLOG_fp = fopen(LogPathName.GetBuffer());
if(readLOG_fp==NULL)
cout<<"Error: opening file\n";
I am trying to write a function in my program that loads a huge text-file of 216,555 words and put them as strings into a set. This works properly, but as expected, it will hang for a few micro seconds while looping through the file. But there is something funky going on with my loop, and it's not behaving properly. Please take the time to read, I am sure there's a valid reason for this, but I have no idea what to search for.
The code, which is working by the way, is this:
ifstream dictionary;
dictionary.open("Dictionary.txt");
if(dictionary.fail())
{
cout<<"Could not find Dictionary.txt. Exiting."<<endl;
exit(0);
}
int i = 0;
int progress = 216555/50;
cout<<"Loading dictionary..."<<endl;
cout<<"< >"<<endl;
cout<<"<";
for(string line; getline(dictionary, line);)
{
usleep(1); //Explanation below (not the hangtime)
i++;
if(i%progress == 0)
cout<<"=";
words.insert(line);
}
The for-loop gets every string from the file, and inserts them in the map.
This is a console-application, and I want the user to see the progress. It's not much of a delay, but I wanted to do it anyway. If you don't understand the code, I'll try to explain.
When the program starts, it first prints out "Loading Dictionary...", and then a "<" and a ">" separated by 50 spaces. Then on the next line: "<" followed by a "=" for every 433 word it loops through (216555/50). The purpose of this is so the user can see the progress. The wanted output half way through the loop would be like this:
Loading dictionary...
< >
<=========================
My problem is:
The correct output is shown, but not at the expected time. It prints out the full progress bar, but that only after it has hanged and are done with the loop. How is that possible? The correct number of '=' are shown, but they all pop out at the same time, AFTER it hangs for some microseconds. I added the usleep(1) to make the hangtime a bit longer, but the same thing happened. The if-statement clearly works, or the '=' would've never showed at all, but it feels like my program is stacking the cout-calls for after the entire loop.
The weirdest thing of all, is that the last cout<<"<"; before the for-loop starts, is also shown at the same time as the rest of its line; after the loop is finished. Why and how?
You never flush the stream, so the output just goes into a buffer.
Change cout<<"="; to cout<<"="<<std::flush;
You need to flush the output stream.
cout << "=" << std::flush;
The program is "stacking the cout-calls". It's called output buffering, and every major operating system does it.
When in interactive mode (as your program is intended to be used), output is buffered by line; that is, it will be forced to the terminal when a newline is seen. You can also have block-buffered (fixed number of bytes between forced outputs; used when piping output) and unbuffered.
C++ provides the std::flush stream modifier to force an output at any point. It can be used like this:
cout << "=" << std::flush;
This will slow down your program a bit; the point of buffering is for efficiency. As you'll only be doing it about 51 times, though, the slowdown should be negligible.