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;
}
Related
I am attempting to read numbers from a text file into a program, but for some reason, the program isn't reading the file. Here is my code:
#include <iostream>
#include <stream>
using namespace std;
int main()
{
ifstream infile;
infile.open ("adventDay1.txt");
if (!infile) { //Check if file is opening
cerr << "Error!"<< endl;
return 0;
}
int dataSize = 0;
infile >> dataSize;
int* arr;
arr = new int[dataSize]; //dynamically allocated array
int measureCount = 0; //Keep track of input from file
for (int i = 0; i < dataSize; i++) {
// infile >> dataSize;
arr[i] = dataSize;
measureCount += 1;
}
cout << measureCount << endl;
delete[] arr; //Delete dynamically allocated memory
return 0;
}
Each time I run it, it just displays the "Error!" message I added. There are 2,000 numbers in the text file, so that should be the expected output based on what I have here. I can't pinpoint the mistake.
Include fstream and ensure that you are opening the file in read mode. Perhaps also define it as ifstream infile("adventDay1.txt")
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;
I've searched and searched this topic and still nothing so I'm resorting to this.
NOTE: Can't use vectors at all
So I'm trying to open up a text file in this program and read the numbers into an array. The program opens it up, and reads them (I'm assuming), but when I read the numbers the back, they are junk numbers. Not really sure where it went wrong, would appreciate some help. Here's my code:
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
void readNumbers(int numbers[]);
const int MAX_SIZE = 12;
int main()
{
int numbers[MAX_SIZE];
readNumbers(numbers);
for (int i = 0; i < MAX_SIZE; i++)
{
cout << numbers[i] << endl;
}
return 0;
}
void readNumbers(int numbers[])
{
int num = 0;
ifstream inFile;
inFile.open("numbers.txt");
if (!inFile)
{
cout << "Cannot open the file" << endl;
}
else
{
inFile >> num;
while(inFile)
{
int i = 0;
numbers[i] += num;
i++;
inFile >> num;
}
}
inFile.close();
}
Output:
1606416400
32767
0
0
0
0
0
0
0
0
0
0
The i variable is local to the loop. Try moving it outside:
int i = 0;
while(inFile)
{
numbers[i] += num;
i++;
inFile >> num;
}
Your array numbers[] is not initialized and you are incrementing nothing but garbage values numbers[i] += num;
hence it prints junk numbers.
If incrementing is important use:
int numbers[MAX_SIZE]={0} //while declaration
If not:
numbers[i]=num //inside while
Also int i=0 should be outside while as i will always be 0 inside while.
You're not initializing your numbers array, so it'll have garbage in it. Why are you using += when storing num in numbers[i]? Shouldn't you be using an assignment there?
numbers[i] = num;
(And also, as previously mentioned, the i index needs to be declared outside the loop, otherwise you're always adding/assigning to the first element in numbers.)
fixed few errors in usage of array.
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
void readNumbers(std::string* numbers);
const int MAX_SIZE = 12;
int nSize = 0;
int main()
{
std::string numbers[MAX_SIZE];
readNumbers(numbers);
for (int i = 0; i < nSize; i++)
{
cout << numbers[i] << endl;
}
return 0;
}
void readNumbers(std::string* numbers)
{
ifstream inFile;
inFile.open("numbers.txt");
if (!inFile)
{
cout << "Cannot open the file" << endl;
}
else
{
while(!inFile.eof())
{
char temp[100] = {0};
inFile.getline(temp, 100);
numbers[nSize++].assign(temp);
if (nSize == MAX_SIZE) break;
}
}
inFile.close();
}
Ok guy i had to make a program to split elements of a string. And after that print those words.
there are some problems i am facing:
1) the array prints more than the size of the words in string i want that it should end printing as soon as last word is printed. i tried to prevent that but it always gives runtime error when i try to break at the last word.
2)is there any other efficient way to split and print ???
#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <string>
using namespace std;
int main()
{
std::string line;
std::getline(cin, line);
string arr[1000];
int i = 0;
int l=line.length();
stringstream ssin(line);
while (ssin.good() && i < l)
{
ssin >> arr[i];
++i;
}
int size = sizeof(arr) / sizeof(arr[0]);
for(i = 0; i <size; i++){
cout << arr[i] << endl;
}
return 0;
}
int size = sizeof(arr) / sizeof(arr[0]);
That is a compile time value, and it's always going to be the number of elements in your array (1000). It has no idea how many strings you assigned to in your loop. You stored the number of successfully read strings (plus 1) in the i variable, so you could do this instead:
int size = i - 1;
But if it were up to me, I would just use a growable structure, like vector (#include <vector>)
std::vector<std::string> arr;
std::string temp;
while (ssin >> temp)
{
arr.push_back(temp);
}
for (auto const & str : arr)
{
std::cout << str << std::endl;
}
/* If you're stuck in the past (can't use C++11)
for (std::vector<std::string>::iterator = arr.begin(); i != arr.end(); ++i)
{
std::cout << *i << std::endl;
}
*/
For general purpose character based splitting, I would much prefer boost::split (I know you can't use it, but for future reference)
std::vector<std::string> arr;
boost::split(arr, line, boost::is_any_of(".,;!? "));
Read up on the function strtok. It is old school but very easy to use.
1) there are a couple of changes you should make to your program:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
std::string line("hello string world\n");
string arr[1000];
int i = 0;
stringstream ssin(line);
while (ssin.good() && i < 1000)
{
ssin >> arr[i++];
}
int size = i-1;
for(i = 0; i < size; i++){
cout << i << ": " << arr[i] << endl;
}
return 0;
}
namely, you don't want to print sizeof(arr)/sizeof(arr[0]) (i.e. 1000) elements. There is no point in the condition i < l
2) stringstream is fine if you just want to separate the single strings; if more is needed, use boost/tokenizer for splitting strings. It's modern c++, once you try it you'll never come back!
this is the best method i think no worry now
#include <sstream>
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include <cstring>
#include <string>
using namespace std;
int main ()
{
std::string str;
std::getline(cin, str);
string arr[100];
int l=0,i;
char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());
// cstr now contains a c-string copy of str
char * p = std::strtok (cstr,".,;!? ");
while (p!=0)
{
//std::cout << p << '\n';
arr[l++]=p;
p = strtok(NULL,".,;!? ");
}
for(i = 0; i <l; i++)
{
cout << arr[i] << endl;
}
delete[] cstr;
return 0;
}
I'm a physics PhD student with some experience coding in java, but I'm trying to learn C++.
The problem I'm trying to solve is to read in data from a .txt file and then output all the numbers > 1000 in one file and all those <1000 in another.
What I need help with is writing the part of the code which actually reads in the data and saves it to an array. The data itself is only separated by a space, not all on a new line, which is confusing me a bit as I don't know how to get c++ to recognise each new word as an int. I have canabalised some code I have got from various sources online-
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include<cmath>
using namespace std;
int hmlines(ifstream &a) {
int i=0;
string line;
while (getline(a,line)) {
cout << line << endl;
i++;
}
return i;
}
int hmwords(ifstream &a) {
int i=0;
char c;
a >> noskipws >> c;
while ((c=a.get()) && (c!=EOF)){
if (c==' ') {
i++;
}
}
return i;
}
int main()
{
int l=0;
int w=0;
string filename;
ifstream matos;
start:
cout << "Input filename- ";
cin >> filename;
matos.open(filename.c_str());
if (matos.fail()) {
goto start;
}
matos.seekg(0, ios::beg);
w = hmwords(matos);
cout << w;
/*c = hmchars(matos);*/
int RawData[w];
int n;
// Loop through the input file
while ( !matos.eof() )
{
matos>> n;
for(int i = 0; i <= w; i++)
{
RawData[n];
cout<< RawData[n];
}
}
//2nd Copied code ends here
int On = 0;
for(int j =0; j< w; j++) {
if(RawData[j] > 1000) {
On = On +1;
}
}
int OnArray [On];
int OffArray [w-On];
for(int j =0; j< w; j++) {
if(RawData[j]> 1000) {
OnArray[j] = RawData[j];
}
else {
OffArray[j] = RawData[j];
}
}
cout << "The # of lines are :" << l
<< ". The # of words are : " << w
<< "Number of T on elements is" << On;
matos.close();
}
But if it would be easier, i'm open to starting the whole thing again, as I don't understand exactly what all the copied code is doing. So to summarise, what I need is it to-
Ask for a filepath in the console
Open the file, and store each number (separated by a space) as an element in a 1D array
I can manage the actual operations myself I think, if I could just get it to read the file the way I need.
Thanks very much
Using C++11 and the Standard Library makes your task fairly simple. This uses Standard Library containers, algorithms, and one simple lambda function.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::string filename;
std::cout << "Input filename- ";
std::cin >> filename;
std::ifstream infile(filename);
if (!infile)
{
std::cerr << "can't open " << filename << '\n';
return 1;
}
std::istream_iterator<int> input(infile), eof; // stream iterators
std::vector<int> onvec, offvec; // standard containers
std::partition_copy(
input, eof, // source (begin, end]
back_inserter(onvec), // first destination
back_inserter(offvec), // second destination
[](int n){ return n > 1000; } // true == dest1, false == dest2
);
// the data is now in the two containers
return 0;
}
Just switch the type of variable fed to your fistream, created from new std:ifstream("path to file") into a int and c++ will do the work for you
#include <fstream> //input/output filestream
#include <iostream>//input/output (for console)
void LoadFile(const char* file)
{
int less[100]; //stores integers less than 1000(max 100)
int more[100]; //stores integers more than 1000(max 100)
int numless = 0;//initialization not automatic in c++
int nummore = 0; //these store number of more/less numbers
std::ifstream File(file); //loads file
while(!file.eof()) //while not reached end of file
{
int number; //first we load the number
File >> number; //load the number
if( number > 1000 )
{
more[nummore] = number;
nummore++;//increase counter
}
else
{
less[numless] = number;
numless++;//increase counter
}
}
std::cout << "number of numbers less:" << numless << std::endl; //inform user about
std::cout << "number of numbers more:" << nummore << std::endl; //how much found...
}
This should give you an idea how should it look like(you shoudnt use static-sized arrays tough) If you got any probs, comment back
Also, please try to make nice readable code, and use tabs/ 4 spaces.
even though its pure C, this might give you some hints.
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#define MAX_LINE_CHARS 1024
void read_numbers_from_file(const char* file_path)
{
//holder for the characters in the line
char contents[MAX_LINE_CHARS];
int size_contents = 0;
FILE *fp = fopen(file_path, "r");
char c;
//reads the file
while(!feof(fp))
{
c = fgetc(fp);
contents[size_contents] = c;
size_contents++;
}
char *token;
token = strtok(contents, " ");
//cycles through every number
while(token != NULL)
{
int number_to_add = atoi(token);
//handle your number!
printf("%d \n", number_to_add);
token = strtok(NULL, " ");
}
fclose(fp);
}
int main()
{
read_numbers_from_file("path_to_file");
return 0;
}
reads a file with numbers separated by white space and prints them.
Hope it helps.
Cheers