beginner C++ importing file, finding sum and average - c++

I'm new to C++ and not sure where to start importing a txt file with 100 numbers, then to make a code to find the sum and average of up to 100 numbers
Can anybody help?

Actually, you already have given the answer yourself. First, find out how to read a file. Then, find out how to convert the text in the file to numbers (you will have to decide what kind of number, like integers, floats or complex). Then, summing up the numbers and computing the average are the next two steps.
Just take one step at a time and make sure you always only try small tasks that you can comprehend in isolation. Even when writing something bigger, it often pays to create a simple test example for one small task first. Also, creating a small test example is a prerequisite to posting at Stack Overflow, see the guidelines for further info.

I hope, this example will help you:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
/* file.txt
2
3
4
6
*/
int main()
{
string line;
ifstream file("file.txt"); // reading from file: http://www.cplusplus.com/doc/tutorial/files/
if (file.is_open())
{
int sum = 0;
while (getline(file, line))
{
int num = atoi(line.c_str()); // convertion from string into int with 'atoi': http://www.cplusplus.com/reference/cstdlib/atoi/
sum += num;
}
file.close();
cout << "Sum is " << sum << endl; // Sum is 15
}
else
{
cout << "Unable to open file" << endl;
}
return 0;
}

Related

g++ printed undesired 00000, why?

Below is my code;
int main(){
ifstream infile;
infile.open(fin);
ofstream outfile;
outfile.open(fout);
char c;
int input_order = 0;
string comp_str = "";
vector <string> pfx_str;
srand(time(NULL));
if (infile.fail())
{
cout << "cannot open file!" << endl;
return 0;
}
while (!infile.fail())
{
cout << input_order << endl;
c = infile.get();
if (c == '\n')
{
if (strcmp(comp_str.c_str(), "") != 0)
{
pfx_str.push_back(comp_str);
}
int num = rand() % pfx_str.size();
while (num == 0)
{
num = rand() % pfx_str.size();
}
for (int i = 0; i < num; i++)
{
outfile << "/" << pfx_str.at(i);
}
outfile << "\n";
input_order++;
pfx_str.clear();
}
else if (c == '/')
{
if (comp_str != "")
{
pfx_str.push_back(comp_str);
}
comp_str = "";
}
else
{
comp_str = comp_str + c;
}
}
infile.close();
outfile.close();
return 0;
}
For small set which consist of 10k inputs, it works.
However, for big set such as using 1600k inputs, it prints out 00000, and does not work. What makes it happened? and how to make it correctly working?
(Previously, I used this code for 1600k input and it works correctly....)
In compile, I used g++ -std=gnu++0x .....
I googled this issue but could not find out the right answer.. And also I could not figure out what this issue comes from....
Thanks,
+
This code is for randomly cutting the input.
This is the example of 1 input set; (to show the input pattern)
/aa/ab/bc/aaa/
Here, I consider 'aa', 'ab', 'bc', and 'aaa' as one component.
And I want randomly cut this input as components unit.
this is the brief step of the code;
1. generate the random number(except 0)
2. ex) I use the above input and the random number is 2.
then I cut this input and only '2' components is left, which is /aa/ab/
(repeat this procedure for each inputs in input text file
=> this input; /aa/ab/bc/aaa/
(inside, it generate random number 2)
output to be printed in output file; /aa/ab/
There is nothing wrong with your code.
I updated your code so that it compiles with g++:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(){
ifstream infile;
infile.open("fin.txt"); // substituted a real file name in here to test
ofstream outfile;
outfile.open("fout.txt"); // ditto here
...the rest is the same as what you put above.
named it test.cpp, and compiled it with:
g++ -lm test.cpp -o test.exe
I wrote a Ruby script to make the input file according to the test set you specified in the comments:
#!/usr/bin/env ruby
File.open( 'fin.txt', 'w') do |f|
1600000.times do
f << "/aa/ab/bc/aaa/\n"
end
end
I then ran the compiled program test.exe, and you totally owe me a beer for watching your line numbers go that high. This is time spent from my life for you that I will never get back. πŸ˜‚
and got an expected fout.txt with
/aa
/aa/ab
/aa
/aa/ab
/aa/ab/bc
/aa/ab/bc
/aa/ab
/aa/ab/bc
/aa/ab
etc.
My guess is that your system's constraints are causing a system fault. I ran this on a typical desktop machine with a ton of memory, etc. If you're running it on an embedded system, it may not have similar resources. At this point, I was tempted to test on a Raspberry Pi, but I'm burning too much time on this already. Just know that there is nothing wrong with your code.
In the future, try to figure out what your coding problem is. Stack Overflow is super forgiving if you've really tried and can't figure out the solution, but you need to show what you've tried and what happened as a result. For problems that started out like this, where you think that you're trying to figure out an algorithmic problem, always give the data set and the unexpected result that occurred.
Good luck!

C++ Creating a variable sized array from ifstream

Just a heads up: My c++ programming skills and terminology is intermediate at best. So please be gentle ;).
I am working on a multi-sort algorithm for a college class. Originally, I built the program to take in an array of 20 integers, since that was as big as the .txt files were. The final lab is now asking to take in files that have 10, 100, 1000, 10000, 100000 and 1000000 different numbers. I originally used an ifstream inside a for loop to read in the ints. Now that I need to read a variable amount of ints from a file, I have run into issues with this code. I have extensively searched this site and Google to find an answer to this problem. I have tried dozens of different code snippets, to no avail. Here is the code I am currently running that works for 20 ints.
int i;
int A[20];
int length;
char unsortedFilename[200];
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
length = (sizeof(A) / sizeof(*A));
for( i = 0; i < length; i++ )
{
unsorted >> A[i];
cout << A[i] << "\n";
}
insertionSort();
I do have other code mixed in there, but it's error checking, selection of duplicate number removal, etc. I would like it so that code like this would run "i" number of times, where "i" is actually the number of ints in the file. Also, as I mentioned earlier, I will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers. Is it going to be as easy as swapping all my ints over to longs?
Thanks for any help you could provide.
As suggested in the comments, use std::vector<int> instead of an array.
Instead of a for loop, use a while loop. Break out of the while loop when there are no numbers to read.
The while loop:
std::vector<int> A;
int item;
while ( unsorted >> item )
{
A.push_back(item);
}
You can sort the std::vector by using std::vector::iterator or simply access the data through the int* returned by A.data().
You can simply read all the numbers into a vector. Then use the vector as you would have used the array.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::string unsortedFilename;
std::cout << "Please type the full name of the file you would like sorted.\n";
std::cin >> unsortedFilename;
std::ifstream is(unsortedFilename);
std::istream_iterator<int> start(is), end;
std::vector<int> A(start, end);
std::cout << "Read " << A.size() << " numbers" << std::endl;
}
What you want is a vector.
try this,
int i;
vector<int> A;
int length;
string unsortedFilename;
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
int temp;
for( i = 0; unsorted >> temp; i++ )
{
A.push_back(temp);
cout << A[i] << "\n";
}
insertionSort();
A vector is basically a dynamic array. It automatically grows as more space is needed. That way it doesn't matter if you have 10, 100, or even 100000 items, it'll automatically grow for you.
Also use a string for your file name, some file names are longer than 200 characters.
Good Luck!
will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers.
Sure it can. 1 Million ints is ~4Mb of memory, which is a trivial amount. You can even declare it static just as you do now int A[1000000];.
But real problem is that you're assuming a fixed length in your code, rather than determine the length from the input. I guess this is what your assignment is trying to teach you, so I won't show you the solution. But consider using ifstream::eof and make your sort accept the length as an argument...

Getting multiple lines of input in C++

The first line contains an integer n (1 ≀ n ≀ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
(Source: http://codeforces.com/problemset/problem/71/A)
How would you get input from the user given n? I tried using a while loop but it doesn't work:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i;
while (i<=n) {
cin>>i ;
i++;
}
}
You probably meant to have something like:
#include <iostream>
int main() {
int n;
cin>>n;
int theInputNumbers[n];
for(int i = 0; i<n; ++i) {
cin >> theInputNumbers[i];
}
}
Your loop is really quite far off of what you need. What you wrote is extremely wrong such that I cannot provide advice other than to learn the basics of loops, variables, and input. The assistance you need is beyond the scope of a simple question/answer, you should consider buying a book and working through it cover to cover. Consider reading Programming Principles and Practice Using C++
Here is a working example of something approximating your question's requirements. I leave file input and output as an exercise up to you. I also make use of C++11's front and back std::string members. You would have to access via array index in older versions.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
int totalWords;
cin >> totalWords;
stringstream finalOutput;
for (int i = 0; i < totalWords; ++i){
string word;
cin >> word;
if (word.length() > 10){
finalOutput << word.front() << (word.length() - 2) << word.back();
}else{
finalOutput << word;
}
finalOutput << endl;
}
cout << endl << "_____________" << endl << "Output:" << endl;
cout << finalOutput.str() << endl;
}
With that said, let me give you some advice:
Name your variables meaningfully. "int i" in a for loop like I have above is a common idiom, the "i" stands for index. But typically you want to avoid using i for anything else. Instead of n, call it totalWords or something similar.
Also, ensure all variables are initialized before accessing them. When you first enter your while loop i has no defined value. This means it could contain anything, and, indeed, your program could do anything as it is undefined behavior.
And as an aside: Why are you reading into an integer i in your example? Why are you then incrementing it? What is the purpose of that? If you read in input from the user, they could type 0, then you increment by 1 setting it to 1... The next iteration maybe they'll type -1 and you'll increment it by 1 and set it to 0... Then they could type in 10001451 and you increment by 1 and set it to 10001452... Do you see the problem with the logic here?
It seems like you are trying to use i as a counter for the total number of iterations. If you are doing this, do not also read input into i from the user. That completely undermines the purpose. Use a separate variable as in my example.

Converting Decimal to binary using only the basics

I have to write a program that converts a decimal number between (1.0 - 99.99) into binary. My teacher said We can ONLY use the things we learned in class so far, witch include: Loops, input/output files, strings, if/else, cmath, and user defined functions. Ive started to program how to convert an integer to binary first before taking on the decimal. I am able to calculate the binary value but I am spitting out my binary in reverse order. So my teacher said to send the remainders(eg: bit values) to a file and read them as a string. Which is were I am now. Still with the same problem. How do I print these values from a string in reverse order?
My attempt so far:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
int number;
int remainder;
string bitValues;
ofstream outFile;
ifstream inFile;
//inFile.open("C:\\Users\\David\\Desktop\\BinaryIn.txt"); // pay no mind to this.
outFile.open("C:\\Users\\David\\Desktop\\BinaryOut.txt");
cout << "Enter a integer to be converted to binary: ";
cin >> number;
while(number != 0)
{
remainder = number % 2;
outFile << remainder << " "; // I send it to the outFile
number /= 2;
}
outFile.close(); // I close because I need to read from it now.
inFile.open("C:\\Users\\David\\Desktop\\BinaryOut.txt"); //I did this so I can read from the same outFile
getline(inFile, bitValues); //had to look up getline(), was not covered in class
// I just came up with this idea, is this Valid??????????
int posisiton = 10;
while(posisiton >= 0)
{
cout << bitValues[posisiton]; // I ever done something like this but It worked!
posisiton--;
}
int pause;
cin >> pause;
return 0;
}
Do you know how to write a recursive function? By doing the recursive call before outputting the remainder (as opposed to afterwards), you will get the effect you want.
1) Forget the file (I don't know how that was going to help. Maybe you misunderstood the teacher). Just write a simple function to reverse the string.
for(int i=0; i<bitValues.length()/2; ++i) {
char t = bitValues[i];
bitValues[i] = bitValues[bitValues.length()-1-i];
bitValues[str.length()-1-i] = t;
}
2) Or instead of using modulo, use a flag to get the bits in order the first time. This isn't code because it more directly relates to your homework, than a simple string reversal.
resize the string to be big enough to hold all the bits
set a mask to have a 1 in the 31st position
for each position in the string
use `&` with the mask to find if it's a one or zero
set the character depending on the bit
shift the mask right one.

count specific things within a code in c++

can anyone help me make this more generalised and more pro?
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
// open text file for input:
string file_name;
cout << "please enter file name: ";
cin >> file_name;
// associate the input file stream with a text file
ifstream infile(file_name.c_str());
// error checking for a valid filename
if ( !infile )
{
cerr << "Unable to open file "
<< file_name << " -- quitting!\n";
return( -1 );
}
else cout << "\n";
// some data structures to perform the function
vector<string> lines_of_text;
string textline;
// read in text file, line by
while (getline( infile, textline, '\n' ))
{
// add the new element to the vector
lines_of_text.push_back( textline );
// print the 'back' vector element - see the STL documentation
cout << lines_of_text.back() << "\n";
}
cout<<"OUTPUT BEGINS HERE: "<<endl<<endl;
cout<<"the total capacity of vector: lines_of_text is: "<<lines_of_text.capacity()<<endl;
int PLOC = (lines_of_text.size()+1);
int numbComments =0;
int numbClasses =0;
cout<<"\nThe total number of physical lines of code is: "<<PLOC<<endl;
for (int i=0; i<(PLOC-1); i++)
//reads through each part of the vector string line-by-line and triggers if the
//it registers the "//" which will output a number lower than 100 (since no line is 100 char long and if the function does not
//register that character within the string, it outputs a public status constant that is found in the class string and has a huge value
//alot more than 100.
{
string temp(lines_of_text [i]);
if (temp.find("//")<100)
numbComments +=1;
}
cout<<"The total number of comment lines is: "<<numbComments<<endl;
for (int j=0; j<(PLOC-1); j++)
{
string temp(lines_of_text [j]);
if (temp.find("};")<100)
numbClasses +=1;
}
cout<<"The total number of classes is: "<<numbClasses<<endl;
Format the code properly, use consistent style and nomenclature and throw out the utterly redundant comments and empty lines. The resulting code should be fine. Or β€œpro”.
Here, I’ve taken the efford (along with some stylistic things that are purely subjective):
Notice that the output is actually wrong (just run it on the program code itself to see that …).
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string file_name;
cout << "please enter file name: ";
cin >> file_name;
ifstream infile(file_name.c_str());
if (not infile) {
cerr << "Unable to open file " << file_name << " -- quitting!" << endl;
return -1;
}
else cout << endl;
vector<string> lines_of_text;
string textline;
while (getline(infile, textline)) {
lines_of_text.push_back(textline);
cout << lines_of_text.back() << endl;
}
cout << "OUTPUT BEGINS HERE: " << endl << endl;
cout << "the total capacity of vector: lines_of_text is: "
<< lines_of_text.capacity() << endl << endl;
int ploc = lines_of_text.size() + 1;
cout << "The total number of physical lines of code is: " << ploc << endl;
// Look for comments `//` and count them.
int num_comments = 0;
for (vector<string>::iterator i = lines_of_text.begin();
i != lines_of_text.end();
++i) {
if (i->find("//") != string::npos)
++num_comments;
}
cout << "The total number of comment lines is: " << num_comments << endl;
// Same for number of classes ...
}
I'm not really sure what you're asking, but I can point out some things that can be improved in this code. I'll focus on the actual statements and leave stylistic comments to others.
cin >> file_name;
To handle file names with spaces, better write
getline(cin, file_name);
int PLOC = (lines_of_text.size()+1);
Why do you claim that there's one more line than there actually is?
if (temp.find("//")<100)
with some complicated comment explaining this. Better write
if (temp.find("//")<temp.npos)
to work correctly on all line lengths.
cout<<"The total number of comment lines is: "<<numbComments<<endl;
Actually, you counted the number of end-of-line comments. I wouldn't call a comment at the end of a statement a "comment line".
You don't count /* */ style comments.
Counting the number of classes as };? Really? How about structs, enums, and plain superfluous semicolons? Simply count the number of occurences of the class keyword. It should have no alphanumeric character or underscore on either side.
Use proper indentation, your code is very difficult to read in its current form. Here is a list of styles.
Prefer ++variable instead of variable += 1 when possible; the ++ operator exists for a reason.
Be consistent in your coding style. If you're going to leave spaces between things like cout and <<, function arguments and the function parantheses do it, otherwise don't, but be consistent. Pick one naming convention for your variables and stick to it. There is a lot about styles you can find on google, for example here and here.
Don't use the entire std namespace, only what you need. User either using std::cout; or prefix all of your cout statements with std::
Avoid needless comments. Everyone knows what ifstream infile(file_name.c_str()); does for example, what I don't know is what your program does as a whole, because I don't really care to understand what it does due to the indentation. It's a short program, so rather than explaning every statement on its own, why not explain what the program's purpose is, and how to use it?
These are all stylistic points. Your program doesn't work in its current form, assuming your goal is to count comments and classes. Doing that is a lot more difficult than you are considering. What if I have a "};" as part of a string for example? What if I have comments in strings?
Don't import the whole std namespace, only things you need from it:
using std::string;
Use a consistent naming convention: decide whether you prefer name_for_a_variable or nameforavariable or nameForAVariable. And use meaningful names: numbComments makes me associate to very different things than would numberOfComments, numComments or commentCount.
If your original code looks like this, I strongly recommend to select a single consistent indentation style: either
if ( ... )
{
...
}
or
if ( ... )
{
...
}
bot not both in the same source file.
Also remove the useless comments like
// add the new element to the vector
This is "only" about the readability of your code, not even touching its functionality... (which, as others have already pointed out, is incorrect). Note that any piece of code is likely to be read many more times than edited. I am fairly sure that you will have trouble reading (and understanding) your own code in this shape, if you need to read it even a couple of months after.
"More professional" would be not doing it at all. Use an existing SLOC counter, so you don't reinvent the wheel.
This discussion lists a few:
http://discuss.techinterview.org/default.asp?joel.3.207012.14
Another tip: Don't use "temp.find("};}) < 100)", use "temp.find("};") != temp.npos;"
Edit: s/end()/npos. Ugh.