I want to count integers from .txt file named "Example.in", which contains (for example):
1 2 3 4 5
3 6 7
5 8
8 9 10 11
1. and returns me a 11, in this case (Integers that repeat counts as 1 - unique number count only). At this point, it only prints out 0 (I think there's problem with opening file at this stage).
2. prints out only the first integers in every row - 1, 3, 5, 8.
int integer_count(){
int count = 0;
int i;
ifstream fin;
fin.open("Example.in"); //.txt file
while(fin >> i)
{
count++;
}
fin.close();
return count; // In this case it should print 14 instead of 11,
because I didn't count out 3, 5 and 8 (which duplicates - haven't figured
out how to make unique count that would close eye for duplicates and
just count unique integers.)
}
When opening the file, you should always check whether or not the opening process has succeed. I believe that file_name.good() is a perfect boolean function to do that. Just make a simple if statement to see if it works, like that:
if(fin.good()) std::cout << "File opened!";
else{ //do something when opening didn't work }
Additioanlly, I believe you also need to write the 'full file name', which in this case (if your file name is exactly "Example.in") would be "Example.in.txt".
For the unique integers problem, there are couple solutions: either make a std::vector that stores already read integers from file and everytime you try to read another one, check whether or not it was already read (fastest algorithm here would be quick/heap/merge sort + binary search, instead of iterating everytime). Always when new integer is added, increase your count value by one.
Second solution is: just store your integers in vector and get rid of the multiples by iterating and erasing. Then count would just be your_vector.size().
"Printing each integer that starts a new line" is a diffrent problem. I would switch from using while(fin >> i) to getline() function. That way, I have each line of file as a string, that can be turned into row of integers. With your while() loop, you do not know when the new line stars, so it's impossible to complete second task (or, after the task 1, you could open a file once again and use another algoritm only for getting the first integers of every line)
Last thing: As many people here stated, using a debugger is highly recommended. It saved me hours of pondering what is wrong, by just simply going through code, line by line. Codeblocks offers a really good debugger, so I encourage you to simply google a codeblocks debugger guide. Even YouTube has some tutorials covering that.
Related
Hello I have been having trouble with my program I've created a list and I have the following program
Its goal is to Read the 5 variables inside the text file 5 variables in 5 different inputs
so I manage to correctly show the list inside the while loop since every time a line is read it's printed untill .eof(End Of File)
My goal is that I am trying to print the list OUTSIDE of the while Loop that has already read and printed those 5 variables 10x the problem is that it repeats the last entered 5 Variables in the list
I and repeats that 10x (size of the list)
I've also tried something like this inside the for loop which I found in here:
int ID=it->ID;
string NAME=it->NAME;
int SEMESTER=it->SEMESTER;
string DIRECTION=it->DIRECTION;
double GRADE=it->GRADE;
As if those are nodes but I am a starter with nodes as well as lists and it seems to have failed
When I look at the code you've provided, I see that in your for loop the a_student is used, which is not updated by/with the iterator. Basically you're not looping over the created student list.
Maybe try using std::for_each (cppreference) it will save you a lot of time:)
Godbolt example: https://godbolt.org/z/fQUhcr
The issue on the left column of code is that you are not de-referencing the iterator. You never set the a_students variable inside the loop, so why do you expect it to change on each iteration?
Write something like:
a_students = *it;
inside the loop. However there is a simpler way. Instead of manually handling the iterators, use:
for (auto a_students: s_stl_list)
{
// do something with each "a_students" which will be AUTOmatically the right type
}
This is a sub-problem of a bigger problem I have posted before. Following is a code snippet from a C++ package I am trying to work with. The intent is to write the values in the float array prob_estimates to the output file. For some seemingly random lines, only some of the values of the array are written. When can that happen? How should I debug it?
int j;
predict_label = predict_probability(model_,x,prob_estimates);
fprintf(output,"%g",predict_label);
for(j=0;j<model_->nr_class;j++) {
fprintf(output," %g",prob_estimates[j]);
fflush(output);
}
fprintf(output,"\n");
I also want to point out that this seems to happen only when the input size is fairly huge. This is a part of a bigger loop which runs per line of an input file (with about 200,000 lines). The prob_estimates array has 500 values per line. The output file writes less than 500 values for some 20-odd lines in the output file.
I ran this a couple of times on a subset (with 20,000 lines) and everything seemed fine.
Update: I tried checking the return value of fprintf after each attempted write and turns out it returns -1 for a lot of lines, when trying to write to the output.
fprintf encountered error at 19th value of line 2109359. Returned -1
fprintf encountered error at 373th value of line 2109359. Returned -1
fprintf encountered error at 229th value of line 2109360. Returned -1
fprintf encountered error at 87th value of line 2109361. Returned -1
fprintf encountered error at 439th value of line 2109361. Returned -1
This is when I modified the above code as follows:
for(j=0;j<model_->nr_class;j++) {
int e = fprintf(output," %g",prob_estimates[j]);
if (e < 0) {
printf("fprintf encountered error at %dth value of line %d. Returned %d",j ,count ,e); }
}
Here count is a variable that counts the number of line. It is incremented at the top of the outer loop (not shown here).
What can I do to figure out why fprintf returns -1?
A few things you could do:
print everything also to console, to see if the problem is in file output or in another place
print model_->nr_class to make sure the number of values is what you expect
Check the output file only after it is closed. Although you fflush output, it might be that other places update the file and don't fflush it. fclose would. I suggest that instead of flushing the file each line, open it in append mode in the beginning of the function, and close it in the end.
Hope this helps
Now you've found that fprintf is returning an error, you need to check the value of errno after the failing call to find out what the actual error cause is.
I get the file size from the index of the page, it's 1024KB and I want it to print 1MB stead of 1024KB, what should I do? (completely noob here)
I got this:
if($row[2]==1) // Rapidshare Check
{
$index=getpage($row[1]);
if(strpos($index,"FILE DOWNLOAD")===false) //check if page contains the word file download if not = bad link
{
mysql_query("UPDATE `v2links` SET `checked`='-1',`lastcheck`=NOW() WHERE `id`=".$row[0]);
print "bad link\n";
logstr("log-c.txt","bad link\n");
}
else
{
preg_match("**/([^\/\|\#\<\(\>\;\s][0-9]*[\s][KB]{2})/**",$index,$match);
$fsize=$match[1];
print $fsize."\n";
logstr("log-c.txt","bad link\n");
//logstr("log-c.txt","$caption | $fsize\n");
mysql_query("UPDATE `v2links` SET `checked`='1',`fsize`='$fsize',`lastcheck`=NOW() WHERE `id`=".$row[0]);
unset($match);
}
}
Thanks
How accurate do you want the conversion to be?
s/0*([0-9]+)[0-9]{3}K/\1M/g
will lop off the last three numbers of a four or greater digit size... but it's a truncation, and doesn't even consider math. (For example, 1999K -> 1M)
A possibly better method would be to s/K/000/g and s/M/000000/g to turn it into a (crude) number of bytes, and then convert as you want back down.
The best possible method would be to process it, if it has a M multiply by 1024*1024; if it has K multiply by 1024. (if it has G, multiply by 1024*1024*1024). Then, process the resulting size however you're trying to.
--Note that it'd be a good plan to store file size as an integer, rather than a string.
For processing and output, a series of if's are probably good enough, and you can set precise tollerances for how big something must be to be displayed as M instead of K.
--Or if you just want M, there's no if, and you just divide by 1024*1024.
I have my 2nd assignment for C++ class which includes Markov chains. The assignment is simple but I'm not able to figure out what is the best implementation when reading chars from files.
I have a file around 300k. One of the rules for the assignment is to use Map and Vector classes. In Map (key is only string) and values will be the Vectors. When I'm reading from the file, I need to start collecting key pairs.
Example:
File1.txt
1234567890
1234567890
If Select Markov k=3, I should have in my Map:
key vector
123 -> 4
456 -> 7
789 -> 0
0/n1 -> 2
234 -> 5
567 -> 8
890 -> /n
/n -> NULL
The professor's suggestion is to read char by char, so my algorithm is the following
while (readchar != EOF){
tempstring += readchar
increment index
if index == Markovlevel {
get nextchar if =!EOF
insert nextchar value in vector
insert tempstring to Map and assign vector
unget char
}
}
I omit some other details. My main question is that if I have 318,000 characters, I will be doing the conditional every time which slows down my computer a lot (brand new MAC pro). A sample program from the professor executes this file in around 5 seconds.
I'm not able to figure out what's the best method to read fixed length words from a text file in C++.
Thanks!
Repeated file reading will slow down the program.
Read the file in blocks, of say size 1024, put into a buffer. Then process this buffer as you require for the assignment. Repeat for the next block till you are done with the file.
Have you actually timed the program? 318,000 conditionals should be a piece of cake for your brand new MAC pro. That should take only microseconds.
Premature optimization is the root of all evil. Make your program work first, optimization comes second.
I am reading in data from a file that has three columns. For example the data will look something like:
3 START RED
4 END RED
To read in the data I am using the following check:
while (iFile.peek() != EOF) {
// read in column 1
// read in column 2
// read in column 3
}
My problem is that the loop usually does an extra loop. I am pretty sure this is because a lot of text editors seem to put a blank line after the last line of actual content.
I did a little bit of Googling and searched on SO and found some similar situations such as Reading from text file until EOF repeats last line however I couldn't quite seem to adapt the solution given to solve my problem. Any suggestions?
EOF is not a prediction but an error state. Hence, you can't use it like you're using it now, to predict whether you can read Column 1, 2 and 3. For that reason, a common pattern in C++ is:
while (input >> obj1 >> obj2) {
use(obj1, obj2);
}
All operator>>(istream& is, T&) return the inputstream, and when used in boolean context the stream is "true" as long as the last extraction succeeded. It's then safe to use the extracted objects.
Presuming iFile is an istream:
You should break out of the loop on any error, not only on EOF (which can be checked for with iFile.eof(), BTW), because this is an endless loop when any format failure sets the stream into a bad state other that EOF. It is usually necessary to break out of a reading loop in the middle of the loop, after everything was read (either successfully or not), and before it is entered.
To make sure there isn't anything interesting coming anymore, you could, after the loop, reset the stream state and then try to read whitespace only until your reach EOF:
while( !iFile.eof() )
{
iFile >> std::ws;
string line;
std::getline(iFile,line);
if(!line.empty()) error(...);
}
If any of the reads fail (where you read the column data), just break out of the while loop. Presumably you are then at the end of the file and reading the last 'not correct' line
Maybe you'll consider it a good idea to handle whitespace and other invalid input then. Perhaps some basic validation of columns 1,2,3 would be desirable as well.
Don't worry about the number of times that you loop: just validate your data and handle invalid inputs.
Basically, check that you have three columns to read and if you don't decide if it's because the file is over or because of some other issue.