The txt file
1 2 3 4 5 col A
2 3 4 5 6 col B
2 3 4 5 6 col C
2 3 4 5 6 col D
2 3 4 5 6 col E
I already know how to store the numbers into 2d array. However, the question also require me to store the words (including the space) into a one-dimensional array. Can somebody tell me how to do this? I am new to C++. Any help will be appreciated.
This would require a basic reading file loop which will read the file line by line, then split it by spaces. For the number it pushes it to the 2d array and the words to a 1d array:
fstream file;
file.open("somefile.txt");
vector<vector<double>> nums;
vector<string> words;
string line;
while(getline(file, line))
{
vector<double> tempNums;
istringstream liney(line); int i = 0; string cell;
while(getline(liney, cell, ' '))
{
if(i < 5) tempNums.push_back(stoi(cell.c_str()));
else words.push_back(" " + cell);
i++;
}
nums.push_back(tempNums)
}
Hope this helps. (This is based on the formatting above)
Related
I am trying to read the contents of a text file into 2D array in C++. The file contains 125 rows with 21 columns of integers (a table of integers). I'm to read this into an array that is 125 rows of 20 columns, skipping column 21 of the file.
I defined the size of the array with variables, but it just reads column 21 into the next row, ignoring the new line. I need it to start each row in the array at the start of the new line from the file but ignore the last item in the table.
I'm not sure if I'm looking for it to skip column 21, or if I'm looking for it to start reading each column at a new line (or both?)
Text file looks like (is this called a matrix?) and it's number separated by 1 space and \n at end.
(The text file was generated by a program to generate rows of 20 numbers and the sum.)
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
" etc
Other solutions I've found can be difficult for me to understand because people write their variables and functions non-descriptively. Some solutions require advanced methods I'm not supposed to use as well, such as vectors and string manipulation. I have currently learned everything before "pointers" so I can only use solutions I've learned in class. I've learned functions, arrays, search/sort, and basics like operators, loops, variables, etc. I'm not supposed to use vectors for this or string manipulation.
I will (eventually) have to sum the numbers in the array (after I extract the first 20 of each row from the file) so to compare the sum from the array final column to the last integer in each row of the file (which is a sum).
My function is (note: We are using namespace std)
void readArray() {
ifstream infile("tableofintegers.txt");
for (int rowcount = 0; rowcount < ROWS; rowcount++) // row loop
{
for (int colcount = 0; colcount < COLS; colcount++) // column loop
{
infile >> twoDArray[rowcount][colcount]; // read to array
}
}
}
These are variables:
const int ROWS = 125;
const int COLS = 20;
I tried this but got a runtime error
file >> array[row][col];
file.ignore(10, '\n');
The error when I tried file.ignore
C:\path\matrix.exe (process 27316) exited with code -2147483645.
Not only is there an error, but it still "wraps" the read starting line two with the sum (last digit) of line 1.) As you can imagine, as this iterates, it keeps pushing the data over further and further.
I expected for the program to stop reading when it reached the limit of the array columns (20) then continue at the next line, but it didn't. My brain tells me something's not logical about that expectation, yet I have a dissonance or something going on. I can't really wrap my head around it. I also tried file.ignore which I expected would ignore 10 characters after the 20th column up to new line, but it just kicked an error and still wrapped.
Note: I'm printing the array to the console. Here is my code for that.
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
cout << setw(5) << dataArray[row][col];
}
cout << endl;
}
My problems here is to take all the integers in a file, and store to an int array (of course without |), and then do something with it (here I just need help to print out the array).
The data from the file is said to be a 10x10 matrix.
My code output is another 10x10 with trash values, as I tried using std::stringstream.
Input:
1|11|2|13|2|2|2|11|13|2
1|11|2|13|2|2|2|13|2|11
1|13|1|13|2|2|2|2|2|2
1|13|1|12|2|2|2|2|2|2
1|13|1|13|1|2|2|2|2|2
1|13|1|13|1|1|2|2|2|2
1|13|1|13|1|1|1|2|2|2
1|13|1|13|1|1|1|1|2|2
1|13|1|13|1|1|1|1|1|2
1|13|1|13|1|1|1|1|1|1
Code:
#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
using namespace std;
int main(){
//read data from file and store in a 2d array
ifstream myfile("input.txt");
string arr[10][20];
for(int i=0;i<10;i++){
for(int j=0;j<20;j++){
getline(myfile,arr[i][j],'|');
}
}
//convert string to int
//use stringstream
int arr2[10][20];
for(int i=0;i<10;i++){
for(int j=0;j<20;j++){
stringstream ss;
ss<<arr[i][j];
ss>>arr2[i][j];
}
}
//print arr2
for(int i=0;i<10;i++){
for(int j=0;j<20;j++){
cout<<arr2[i][j]<<" ";
}
cout<<endl;
}
myfile.close();
return 0;
}
The output should be:
1 11 2 13 2 2 2 11 13 2
1 11 2 13 2 2 2 13 2 11
1 13 1 13 2 2 2 2 2 2
1 13 1 12 2 2 2 2 2 2
1 13 1 13 1 2 2 2 2 2
1 13 1 13 1 1 2 2 2 2
1 13 1 13 1 1 1 2 2 2
1 13 1 13 1 1 1 1 2 2
1 13 1 13 1 1 1 1 1 2
1 13 1 13 1 1 1 1 1 1
My output:
1 11 2 13 2 2 2 11 13 2
1 13 2 2 2 2 2 2 13 1
1 2 2 2 2 2 13 1 13 1
1 2 2 2 13 1 13 1 1 1
1 2 13 1 13 1 1 1 1 1
1994842136 12 7086696 7085352 1994774642 0 1994842144 1994771436 0 0
6416848 2004213955 7086772 6416972 12 7086696 0 4 48 1994842112
2004213726 1 7149280 7149288 7086696 0 1988425164 0 2003400672 12
1999860416 6416972 2 1999966512 1999657456 1999691632 1999846272 1999845632 1999819744 1999860464
4194304 1994719472 0 6417024 0 6418312 2004471984 775517426 -2 6417120
Two issues: You try to read 10x20 when there is only 10x10 in the file. Further your code assumes that there is a | between all adjacent numbers, but thats not the case. There is no | between the last number in a line and the first in the next line.
Change the size accordingly and read full lines before you split them at |:
string arr[10][10];
for(int i=0;i<10;i++){
std::string line;
getline(myfile,line);
std::stringstream linestream{line};
for(int j=0;j<10;j++){
getline(linestream,arr[i][j],'|');
}
}
Live Demo
This is minimum changes on your code. Next I would suggest to extract integers from the stream directly instead of first extracting string and then convert them to integers (by placing the strings into another stream and then extracting the integer, you could do this already with the ifstream).
The basic problem is that the content of your input file doesn't map well to the operation that you're trying to do on that content. In particular, you've assumed that every character in your input file is separated by a | character which is not the case since there is a newline between the last character in any particular line and the first character in the next line.
Also, do note that you have created a 2D array that has 10 rows and 20 columns but your input file has only 10 rows and 10 columns.
Better would be to use a 2D std::vector as shown below:
#include <iostream>
#include<sstream>
#include<string>
#include<vector>
#include <fstream>
int main()
{
std::ifstream inputFile("input.txt");
std::string line;
//create a 2D vector
std::vector<std::vector<int>> arr;
int num = 0; //this will hold the current integer value from the file
std::string numTemp;
if(inputFile)
{
while(std::getline(inputFile, line)) //read line by line
{
std::vector<int> temp;//create a 1D vector
std::istringstream ss(line);
while(std::getline(ss, numTemp, '|') && (std::istringstream(numTemp) >> num)) //read integer by integer
{
//emplace_back the current number num to the temp vector
temp.emplace_back(num);
}
//emplace_back the current 1D vector temp to the 2D vector arr
arr.emplace_back(temp);
}
}
else
{
std::cout<<"input file cannot be opened"<<std::endl;
}
//lets confirm if our 2D vector contains all the elements correctly
for(const auto& row: arr)
{
for(const auto& col: row)
{
std::cout<<col<<" ";
}
std::cout<<std::endl;
}
return 0;
}
The output of the above program can be seen here.
The advantage of using std::vector over built in array is that :
You don't have to know the how many rows and columns are there in the input.txt file beforehand.
It is not necessary that all rows have the same number of columns.
That is, using std::vector is flexible.
Each line of my file consists of an unknown number of integers, which are separated by spaces. I would like to read in each line as a vector of those integers.
Here is an example of such file:
11 3 0 1
4 5 0 3
2 3 4 1
23 4 25 15 11
0 2 6 7 10
5 6 2
1
11
I've been able to read in small amounts of data successfully using the following method (Note that outer_layers is a vector that contains these vectors I'm trying to populate):
for (int i = 0; i < outer_layers.size(); i++)
{
while (in >> temp_num)
{
outer_layers[i].inner_layer.push_back(temp_num);
if (in.peek() == '\n')
break;
}
}
However, when I'm trying to read in larger amounts of data, sometimes it'll read in two lines under one vector. In one of the files, out of 24 lines, it read two-liners on two occasions, so last two vectors did not have any data.
I can't wrap my head around it. Any ideas what I'm doing wrong?
EDIT: Something interesting I've noticed in some of the lines of the trouble-maker file is this:
Let's say there are three lines.
23 42 1 5
1 0 5 10
2 3 11
Line #1 reads in just fine as 23 42 1 5; however, line #2 and #3 get read together as 1 0 5 10 2 3 11.
In Notepad++ they look just fine, each on their own lines. However, in Notepad, they look like this:
23 42 1 51 0 5 10 2 3 11
If you notice, the 5 (last integer of line #1) and 1 (first integer of line #2) are not separated by spaces; however, 10 and 2 are separated by a space.
I've noticed that behavior on any double-read-in lines. If they are separated by a space, then they're both read in. Not sure why this is occurring, considering there should still be a new line character in there for Notepad++ to display the on separate lines, am I right?
I'm not sure how your outer_layers and inner_layers is setup, but you can use std::getline and std::stringstream to fill your vectors something like this :
std::vector< std::vector<int> > V ;
std::vector <int> vec;
std::ifstream fin("input.txt");
std::string line;
int i;
while (std::getline( fin, line) ) //Read a line
{
std::stringstream ss(line);
while(ss >> i) //Extract integers from line
vec.push_back(i);
V.push_back(vec);
vec.clear();
}
fin.close();
for(const auto &x:V)
{
for(const auto &y:x)
std::cout<<y<<" ";
std::cout<<std::endl;
}
I have a text file containing names and numbers. The name or the string contains 15 chars and I need to put it to the string. I'm working with structures.
struct grybautojas{
string vardas;
int barav, raudon, lep, diena;
}gryb[100];
After that, there are simple calculations which is done right, the problem is, it only reads everything once. After taking a first "box" of information, it just stops. Everything else in the result file is either blank as a string or 0 as an integer.
Here's my input function:
void ivedimas(){
char eil[16];
int b,r,l;
inFile >> n;
inFile.ignore();
for(int i=0;i<n;i++){
inFile.get(eil,15);
gryb[i].vardas=eil;
inFile >> gryb[i].diena;
gryb[i].barav=0, gryb[i].raudon=0, gryb[i].lep=0;
for(int m=0;m<gryb[i].diena;m++){
inFile >> b >> r >> l;
gryb[i].barav+=b, gryb[i].raudon+=r, gryb[i].lep+=l;
}
inFile.ignore();
}
inFile.close();
}
And here's the file containing data:
4
Petras 3
5 13 8
4 0 5
16 1 0
Algis 1
9 6 13
Jurgis 4
4 14 2
4 4 15
16 15 251
1 2 3
Rita 2
6 65 4
4 4 13
What's the problem?
inFile.get(eil,15);
Rita 2
Petras 3
00000000011111
12345678901234
I don't count 15, I count 14. Also, some of your lines seem to have a space at the end. You should rewrite your input logic to be much more robust. Read lines and parse them.
This line:
inFile.get(eil,15);
is reading the number that follows the name.
When you try to read the number (3 in your example), you get the next one (5) instead.
I need to count the frequencies of different integers together in a binary file, how can I do this? I do not wish to convert to string, because that would slow down my program down.. I think...
vector<uint32_t> buf(2);
map<uint32_t, uint32_t> mymap;
if(file.is_open())
{
while (file.read(reinterpret_cast<char*>(&buf[0]), sizeof(uint32_t)*numcols))
{
for(size_t i = 0; i < numcols; ++i)
{
mymap[buf[i]]++; // **---> I need help here**
}
}
}
file.close();
How can I make the key to the map so that it always counts those integers together
Yep.. how many times I see integer pairs consecutively, like how many times (1,2), or (8, 14), or (7,3).
1 2
1 2
7 3
8 14
8 14
8 14
1 2 --> 2 times
7 3 --> 1 time
8 14 --> 3 times
numcols == 2 correct.
One option might be to have the map use pair<uint32_t, uint32_t>s as keys. That way you're explicitly mapping from pairs of uint32_ts to the frequency with which they appear.