Reading a text file into a vector from the command line - c++

Whenever I try to see the contents inside the vector I get "segmentation fault" any idea why that is? Do I not read in the values properly?
#include <iostream>
#include <cstdlib> // atoi function
#include <vector>
#include <fstream>
using namespace std;
vector<int> list ; // global vector
int main (int args , char * argv[])
{
ifstream in(argv[1]);
//ofstream out(argv[2]);
int listSize = atoi (argv[2]);
cout << listSize << endl;
int i = 0;
cout << argv[1] << endl;
in.open(argv[1]);
while (i < listSize)
{
in >> list[i];
cout << "test2" << endl;
i++;
}
in.close();
for( int k=0; k <listSize; k++){
cout<< list[k] << endl;
}
return 0;
}
the text file contains these numbers:
5 6 7 11 12 13

A vector doesn't automatically come with slots. You have to either reserve slots or use push_backto append items to the vector:
//...
int value;
in >> value;
list.push_back(value);

Read what's in the file using getline. See sample code below:
ifstream InFile(argv[1], ios::in); /*Open file from arg[1]*/
std::string LineContent;
getline(InFile, LineContent); /*Save line per line */
With your line saved in a string, you can now transfer the data from that string to the vector, see:
vector<int> list;
list.push_back(atoi(LineContent.c_str()));
Now, you can print out what's in the file:
for (int i = 0; i < list.size(); i++)
cout << list[i] << endl;

Related

I am trying to return an array sorted in descending order, Is there a reason my code is returning no output to the output file?

#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inputFile;
ofstream outputFile;
string filename;
const int SIZE = 20;
float numbers[SIZE];
int i = 0;
float temp;
cin >> filename;
// Open files and if input file is not open return error message and end program
outputFile.open("output.txt");
inputFile.open(filename);
if (!inputFile)
{
cout << "File not found" << endl;
return -1;
}
// Get numbers from input file and sort them from largest to smallest
while (inputFile >> numbers[i])
{
i++;
}
for (i = 0; i < sizeof(numbers); i++)
{
if (numbers[i] < numbers[i + 1])
{
temp = numbers[i];
numbers[i + 1] = numbers[i];
numbers[i] = temp;
}
}
// Take numbers in new order and output them to output file
for (i = 0; i < sizeof(numbers); i++)
outputFile << numbers[i] << ", ";
// Close all files
outputFile.close();
inputFile.close();
return 0;
}
Write a program that opens a text file to load a sequence of real values, separated by commas and whitespaces. You can safely assume that the number of real values in all the files is less than or equal to 20. The program then sorts these values in the descending order, and outputs the sorted numbers to another text file. The user only enters the input file. This is the problem I am trying to solve.
Using modern C++ features makes this much easier than fixed size arrays and keeping track of how many items you've read in.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <iterator>
int main() {
std::ifstream in_file;
std::ofstream out_file;
const std::size_t SIZE = 0;
std::vector<float> numbers;
std::string in_file_name;
std::cin >> in_file_name;
in_file.open(in_file_name);
if (!in_file) {
std::cerr << "File not found" << std::endl;
return -1;
}
std::copy(std::istream_iterator<float>(in_file),
std::istream_iterator<float>(),
std::back_inserter(numbers));
in_file.close();
std::sort(numbers.begin(), numbers.end());
out_file.open("output.txt");
std::copy(numbers.begin(),
numbers.end(),
std::ostream_iterator<float>(out_file, ", "));
out_file.close();
return 0;
}

How to get the average from data.txt file with C++?

Our professor wants us to fix the code which counts the amount of values in a data.txt file and computes their average. Here is the code:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
string s;
ifstream f;
int nItems;
double * data;
double sum=0;
vector < double > data2;
double item;
cout <<"File name: ";
cin >> s;
f.open (s.c_str() );
while (! f.eof() )
{
f >> item;
data2.push_back(item);
}
for (int i =0; i < nItems; i++)
{
sum += data[i];
}
cout << "The average is " << sum/nItems <<".\n";
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
His instructions were:
Modify code worked on today so that the average of data in vector < double > data is computed properly. Right now the code just gives you a value which isn't the average.
I tried changing the nItems variable into 12 and that seemed to work, but the goal of the code is to determine nItems and use that to find the average, which I can't seem to figure out.
You use data for which you haven't allocated any memory when you summarise That causes undefined behaviour. You've stored your values in data2. Remove variables you don't need. Also, using namespace std is considered bad practice.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric> // std::accumulate
int main(int, char**) {
std::string filename;
std::cout << "File name: ";
std::cin >> filename;
std::ifstream f(filename); // no need for .c_str()
std::vector<double> data;
double item;
// instead of checking for eof, check if extraction succeeds:
while(f >> item) {
data.push_back(item);
}
// a standard way to sum all entries in a container:
double sum = std::accumulate(data.begin(), data.end(), 0.);
std::cout << "The sum is " << sum << "\n";
// use the containers size() function. it returns the number of items:
std::cout << "The average is " << (sum / data.size()) << "\n";
}
Hey looks like you weren't reading the numbers in from the txt file.
Here I look through the input file once just to count how many numbers there are
so I can make the array.
Then I look through it again to fill the array.
#include <cstdlib>
#include <iostream>
#include <fstream>
// f here stands for find, fstream gives you files
using namespace std;
int main(int argc, char *argv[]) {
string s;
ifstream f;
// input file stream
int nItems;
double * data;
double sum=0;
cout << "File name: ";
cin >> s;
f.open (s.c_str() );
// s.c_str will return a char array equivalent of the string s
nItems=0;
int input =0;
while (f >> input) {//first loop reading through file to count number of items
nItems++;
}
f.close();
data = new double[nItems]; //Make the array
f.open (s.c_str() );//open file for second read
int i=0;
while (f >> input) {//Second loop through file fills array
data[i] = input;
i++;
}
f.close();
for (int i = 0; i < nItems; i++) {
sum += data[i];
}
cout << "The average is " << sum / nItems << ".\n";
cout << endl;
system("pause");
return 0;
}

printing weird symbols to output file, c++

I am writing a code that reads an input file of numbers, sorts them in ascending order, and prints them to output. The only thing printed to output is some really freaky symbols.
Here is my code
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
int i, y, temp, num[20];
char file_nameI[21], file_nameO[21];
ofstream outfile;
ifstream infile;
cout << "Please enter name of input file: ";
cin >> file_nameI;
infile.open(file_nameI);
if (!infile)
{
cout << "Could not open input file \n";
return 0;
}
cout << "Please enter name of output file: ";
cin >> file_nameO;
outfile.open(file_nameO);
if (!outfile)
{
cout << "Could not open output file \n";
return 0;
}
for (i = 0; i < 20; i++)
{
y = i + 1;
while (y < 5)
{
if (num[i] > num[y]) //Correction3
{
infile >> temp;
temp = num[i];
num[i] = num[y];
num[y] = temp;
//y++; //Correction4
}
y++;
}
}
for (i = 0; i < 5; i++)
outfile << "num[i]:" << num[i] << "\n";
return 0;
}
Here is my input
6 7 9 0 40
Here is the output
 „Ô,üþ 54
H|À°ÀzY „Ô,üþ 0
Problems with your code are already mentioned in the comments but again:
First problem is uninitialized elements of num[20] - elements of num have indeterminate values so accessing any of them triggers undefined behavior. You should first read them from the file or at least initialize them to some default value.
The part of code that should most likely do the sorting is just completely wrong. If you'd like to implement your own function for sorting, you can pick up some well-known algorithm like e.g. quicksort - but C++ Standard Library already provides sorting function - std::sort.
Besides obvious mistakes:
You are using char[] - in C++ it's almost always better to use std::string.
Your static array can only store 20 values and you are reading those from a file. You can use std::vector which can grow when you add more elements than its current capacity. It also automatically fixes the problem with uninitialized elements of num[20].
As mentioned in the comments you can organize your code and improve readability by splitting it into functions.
Here you've got it quickly rewritten. This code uses std::string instead of char[], std::vector to store the numbers and std::sort. If there is something you don't understand here, read SO documentation:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> read_file(ifstream& in_file)
{
vector<int> vec;
int value;
while (in_file >> value)
{
vec.push_back(value);
}
return vec;
}
void write_file(ofstream& out_file, const vector<int>& values)
{
for (size_t i = 0; i < values.size(); ++i)
out_file << "value #" << i << ": " << values[i] << '\n';
}
int main()
{
string input_filename, output_filename;
ofstream out_file;
ifstream in_file;
cout << "Please enter name of input file: ";
cin >> input_filename;
in_file.open(input_filename);
if (!in_file)
{
cout << "Could not open input file\n";
return 0;
}
cout << "Please enter name of output file: ";
cin >> output_filename;
out_file.open(output_filename);
if (!out_file)
{
cout << "Could not open output file\n";
return 0;
}
auto numbers = read_file(in_file);
sort(begin(numbers), end(numbers));
write_file(out_file, numbers);
return 0;
}
You might forgot to store values in num array. Just update your code as follows and it will work.
infile.open(file_nameI);
if (!infile){
cout << "Could not open input file \n";
return 0;
} else{
i = 0;
while (infile >> num[i]){
i++;
}
}

Creating array after getting variable in other function

A text file looks like this:
3
String
String2
String3
I must create a function to read all the strings from text file, save them to array and then display it in main function. For example
void reading(int & count, string strings[]) {
ifstream fd "text.txt";
fd >> count;
for (int i=0; i<count; i++)
fd >> strings[i];
fd.close();
And main function:
int main() {
int count=0;
string strings[100];
reading(count, strings);
for (int i=0; i<count; i++)
cout << strings[i] << endl;
The number of strings is written in first line of text file. How can I create an array of exactly that number? I need it to be able to access it in main/other functions. (For example function for writing into another text file).
In case there is a super important reason to do that with an array, then use std::new, like this:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int reading(string** str_array, int& size, string filename) {
ifstream infile(filename.c_str());
if(!infile) {
cerr << "Unable to access file!\n";
return -1;
}
int n = 0;
infile >> size;
try{
*str_array = new string[size];
string str;
for (; n < size && infile; ++n) {
infile >> str;
(*str_array)[n] = str;
}
if (n != size)
cerr << "ERROR, read less than " << size << " strings!!\n\n";
} catch(bad_alloc& exc) {
return -2;
}
return 0;
}
int main() {
string* str_array = NULL;
int size;
if(reading(&str_array, size, "test.txt")) {
cerr << "Din't read file, exiting...\n";
return -1;
}
for(int i = 0; i < size; ++i)
cout << str_array[i] << endl;
delete [] str_array; // DO NOT FORGET TO FREE YOUR MEMORY
str_array = NULL;
return 0;
}
Output:
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
String
String2
String3
However, you are in c++ and you are not using an std::vector for this?
Look how simple it is with that:
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int reading(vector<string>& v, string filename) {
ifstream infile(filename.c_str());
if(!infile) {
cerr << "Unable to access file!\n";
return -1;
}
int N = -1, n = 0;
infile >> N;
string str;
for (; n < N && infile; ++n) {
infile >> str;
v.push_back(str);
}
if (n != N)
cerr << "ERROR, read less than " << N << " strings!!\n\n";
return 0;
}
int main() {
vector<string> v;
if(reading(v, "test.txt")) {
cerr << "Din't read file, exiting...\n";
return -1;
}
for(size_t i = 0; i < v.size(); ++i)
cout << v[i] << "\n";
return 0;
}
Output:
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
String
String2
String3
Edit:
We have to pass a pointer to what we want to modify (that is, the string*), otherwise the changes we apply won't take place. Test it yourself, pass a string* as a parameter instead of string**, modify the body of the function and she what happens.
To get the idea, imagine we want to write to the pointer, the new address, which new gave us and holds the memory requested. We do write that address inside the function, but when the function terminates, we want the changes to be persistent. See my Functions in C as an example.
Allocate an array on the heap, like this:
std::string* stringArr = new std::string[(place amout of strings here)];
and don't forget to delete it at the end of main()
delete stringArr[];
Variables / arrays on the heap are dynamic so the size doesn't have to be fixed!
std::string* → This is a pointer that points to the address of the beginning of this array in your memory. (Just to let your computer know where it is)
stringArr → the name of the array
new → allocates new memory
std::string[size] → says how much to allocate
I've seen some answers that were talking about "vectors". If you wanna use them you could have a look at this page for more info! →
Vector documentation
use a vector
#include <vector>
#include<fstream>
#include <iostream>
using namespace std;
void reading(int & count, vector<string> * strings) {
ifstream fd("text.txt");
fd >> count;
string T;
for (int i=0; i<count; i++)
{
fd >> T;
strings->push_back(T);
}
fd.close();
}
int main() {
int count=0;
vector<string> strings;
reading(count, &strings);
for (int i=0; i<count; i++)
cout << strings[i] << endl;
}

Fill an array with getline loop

Would like to fill an array one line at a time from the file "Hello.cpp". However if I do it the way below I fill the entire file [w] times instead of just grabbing one line from the file for each iteration of i.
If I remove the { } from getline then the array is filled with the last line of "Hello.cpp" [w] times.
I am not sure how to get a new [i] each time from the Hello.cpp file.
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
int w=0;
ifstream in("Hello.cpp");
string s;
while(getline(in, s))
w=w+1; //first count the number of lines in the file for the array
string a[w];//make an array big enough for the file
for(int i = 0; i < w ; i++) {
ifstream in("Hello.cpp");
string s;
while(getline(in, s)){
a[i] = s;
cout << i + 1 << " " << s << endl;
}
}
I would close your file before reopening it (best practice).
Looks to me like you need to move your file open (ifstream constructor) outside of your for (do you really want to open the file w times)? Since you bother to count the lines first don't you really want something like this:
ifstream in1("Hello.cpp");
for(int i = 0; i < w ; i++) {
getline(in1, a[i]);
cout << i + 1 << " " << a[i] << endl;
}