Bringing in data of two separate values from txt file into array - c++

So I am reading in data from a text file and putting it into an array. My code works fine and outputs the data except that instead of outputting data like
Q 5
it outputs it like this
Q
5
This is part of a greater assigment where I put all the values into a queue and sort them based on the numerical value which in the example above would be 5. But I just want help trying to get the data to come out like
Q 5
Here is my code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
const int alphabet = 52;
char letter[alphabet];
int count = 0;
ifstream dataIn;
dataIn.open("CharInput.txt");
if (!dataIn)
{
cout << "Error opening data file\n";
}
else
{
while (count < alphabet && dataIn >> letter[count])
count++;
dataIn.close();
cout << "The letters and their position are: " << endl;
for (int stuff = 0; stuff < count; stuff++)
{
cout << letter[stuff] << endl;
}
}
system("PAUSE");
return 0;
}
The data file is names CharInput.txt and has:
26
Q 5
W 3
E 8
R 7
T 2
Y 9
U 0
I 9
O 6
P 1
A 2
S 2
D 4
F 3
G 6
H 9
J 8
K 0
L 3
Z 1
X 5
C 7
V 4
B 7
N 2
M 8

The data are output in lines because you are printing them ending with std::endl, which by its name, ending current line.
Instead, use a white space between each element and its count:
for (int stuff = 0; stuff < count; stuff += 2)
{
cout << letter[stuff] << " " << letter[stuff + 1] << std::endl;
}

Related

How do divide txt file numbers into a positive number txt file and negative number txt file

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
int main()
{
int masivs[24], x = 0, y = 0;
int negativi[20];
int pozitivi[20];
ifstream f;
f.open("f.txt");
while (f.good() && x < 24)
f >> masivs[x++];
f.close();
cout << masivs[1];
ofstream f2("f2.txt");
ofstream f1("f1.txt");
for (x = 0; x < 24; x++)
if (masivs[x] >= 0)
pozitivi[x] = masivs[x];
else
negativi[x] = masivs[x];
for (int k = 0; k < 8; k++)
{
f2 << negativi << endl;
}
for (int k = 0; k < 15; k++)
{
f1 << pozitivi << endl;
}
}
Ive been trying to find out how to do this for 2 days and im going crazy. Just please tell me how to do it. Im trying to divide the f.txt file numbers into f1.txt with the positives and f2.txt with the negatives. I have to read the f file with an array adn then write the positives in f1 and negatives in f2. and all the zeros in f3. Pls help ive been trying to find info on this but i cant do it.
the f.txt numbers:
-9
-8
-7
-6
-5
-4
-3
-2
-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
You have two major problems. One benign and one which leads to undefined behavior.
The benign problem is the statement
f2<<negativi<<endl;
This is exactly the same as
f2 << &negativi[0] << endl;
In other words, it writes a pointer to the first element of negativi.
The more serious problem is a buffer overflow in the loop
for (x = 0; x < 24; x++)
if (masivs[x] >= 0)
pozitivi[x] = masivs[x];
else
negativi[x] = masivs[x];
Here you use the same index x for both pozitivi, negativi and masivs. This index is only valid for masivs.
The loop as it works now with a single index x will not only put holes in the pozitivi and negativi arrays, but also go out of bounds of both.
The solution is to add another index, one each for the pozitivi and negativi arrays:
unsigned p = 0; // Index for positive number array
unsigned n = 0; // Index for negative number array
for (unsigned x = 0; x < 24; x++)
{
if (masivs[x] >= 0)
pozitivi[p++] = masivs[x];
else
negativi[n++] = masivs[x];
}
Afterwards you can use p and n as sizes for the corresponding array, to use when you write the result to the files.
And as mentioned in a comment to the question, the arrays aren't really needed which makes much of the code moot, and the whole program much simpler. And simplicity is better, as there's less chance of errors.
You can do a simple while(getline()) loop...
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <fstream>
int main()
{
int lineNumber, it = 0;
std::string line;
std::ifstream f("f.txt");
std::ofstream f1, f2;
f1.open("f1.txt");
f2.open("f2.txt");
while(std::getline(f, line)) //reads each line of f.txt ino a string
{
try
{
lineNumber = std::stoi(line);
}
catch(std::invalid_argument& e) //if value is not a number
{
std::cout << "VALUE IS NOT A NUMBER ON ITERATION " << it << '\n';
//std::abort();
continue;
}
catch(std::out_of_range& e) //if value is above +-2^32 +-1
{
std::cout << "VALUE OUT OF RANGE ON ITERATION " << it << '\n';
//std::abort();
continue;
}
if(lineNumber > 0)
{
f1 << lineNumber << '\n';
}
else
{
f2 << lineNumber << '\n';
}
it++;
}
f1.close();
f2.close();
}
This will get your desired output, file f1.txt containing all the positive numbers, and file f2.txt containing all the negative numbers.

Moving pieces in an array? C++

How could you move array characters?????????
Here is some basic code with high-level comments. It is not exactly as you desire. But since you have provided some code it is nearly there.
After reading the comments and understanding what is happening, it should be relatively straightforward to modify the below code to your requirements:
#include <iostream>
void printArray(int gameboard[5][5]){
std::cout << "This is what the gameboard looks like now:" << std::endl;
for ( int i = 0; i < 5; i++ ) {
for ( int j = 0; j < 5; j++ ) {
std::cout << gameboard[i][j] << ' ';
}
std::cout << std::endl;
}
}
int main() {
// Declare array and print what it looks like
int gameboard[5][5] = { {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}};
printArray(gameboard);
// Get input for which coordinates the user wants to swap
int row1, column1, row2, column2;
std::cout << "Please enter the coordinates of the first piece:" << std::endl;
std::cout << "Row:";
std::cin >> row1;
std::cout << "Column:";
std::cin >> column1;
std::cout << "Please enter the coordinates of the second piece:" << std::endl;
std::cout << "Row:";
std::cin >> row2;
std::cout << "Column:";
std::cin >> column2;
// Swap values at provided coordinates by using a temp variable
int temp = gameboard[row1][column1];
gameboard[row1][column1] = gameboard[row2][column2];
gameboard[row2][column2] = temp;
printArray(gameboard);
return 0;
}
Example Usage:
This is what the gameboard looks like now:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Please enter the coordinates of the first piece:
Row: 0
Column: 0
Please enter the coordinates of the second piece:
Row: 4
Column: 4
This is what the gameboard looks like now:
5 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 1
Tasks TO-DO for you:
Change printArray to allow arrays of varying sizes not just 5 x 5.
Ensure user input for row, column and value are numbers.
Ensure user input row, and column values are within the bounds of the array.

Store Matrix with integer from a text file into an array in c++

I have a file named matrices.txt that has two matrices that are 3 by 3.
They are:
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
I'm trying the read from this file and store it into an array proto_matrix to later split that into two matrices.
The problem I'm having is that I can't store the numbers in the array.
My code is
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
int proto_matrix[2 * dimension];
// make array of two matrices combined, this will be split into two matrices
ifstream matrix_file("matrices.txt");
while(matrix_file)
{
matrix_file >> proto_matrix[i];
}
matrix_file.close();
}
I tried debugging the code and it seems like the no integer is stored in the array, just random numbers.
This:
int proto_matrix[2 * dimension];
is a Variable Length Array (VLA), which is not Standard C++, but is supported by some compiler extensions. If compile with g++ -pedantic main.cpp, you will surely get an error.
That means that you need to dynamically allocate your memory, if you had to use an array.
You really don't though, C++ offers std::vector, which can achieve what you want relatively easily. I say relatively, because you have two matrices in one file, which makes parsing the file a bit tricky. Usually we put the one matrix in one file, and the other matrix to another file.
A 2D array can be represented as a 2D vector.
You want two matrices, thus two 2D vectors.
For that reason, I will use an array of size 2 (fixed size!), where every element is going to be a 2D vector.
Moreover, I will keep track of which matrix I am reading from the file right now (the first or the second), and how many rows I have read currently, in order to populate the correct cell of the matrix.
index is going to be equal to 0 or 1, to index the array.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
vector< vector<int> > v[2];
v[0].resize(n);
v[1].resize(n);
// make array of two matrices combined, this will be split into two matrices
ifstream matrix_file("matrices.txt");
string line;
int rows_read = 0, cols_read = 0, index = 0;
while (std::getline(matrix_file, line))
{
std::istringstream iss(line);
int a, b, c;
if (!(iss >> a >> b >> c)) { break; } // error
// process tuple (a, b, c)
if(index == 0 && rows_read >= n)
{
rows_read = 0;
index = 1;
}
//cout<<"rows = " << rows_read << " " << index<<endl;
v[index][rows_read].push_back(a);
v[index][rows_read].push_back(b);
v[index][rows_read++].push_back(c);
}
matrix_file.close();
for(int i = 0; i < 2; ++i)
{
cout << "Printing matrix " << i << endl;
for(auto& matrix: v[i])
{
for(auto& number: matrix)
cout << number << " ";
cout << endl;
}
}
return 0;
}
Output:
Printing matrix 0
1 2 3
4 5 6
7 8 9
Printing matrix 1
1 2 3
4 5 6
7 8 9
PS: Unrelated to your problem, but What should main() return in C and C++? An int.
Based on my answer, I will post here a cleaner example, which achieves what your code tries to achieve: Read all the numbers in a 1D data structure (which will be split in two matrices somehow later).
So for that case, the code boils down to just this:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
int i = 0, j, k = 0, n, dimension;
cout << "Enter the dimension of square matrices (3 by 3 would be 3) \n";
cin >> n;
dimension = n * n;
// make array of two matrices combined, this will be split into two matrices
vector<int> proto_matrix;
ifstream matrix_file("matrices.txt");
string line;
while (std::getline(matrix_file, line))
{
std::istringstream iss(line);
int a, b, c;
if (!(iss >> a >> b >> c)) { break; } // error
proto_matrix.push_back(a);
proto_matrix.push_back(b);
proto_matrix.push_back(c);
}
matrix_file.close();
for(auto& number: proto_matrix)
cout << number << "\n";
return 0;
}
You could just read all the values into a flat container (such as std::vector) and do the re-arrangement at a later point. The following code may give you an idea:
#include <vector>
#include <fstream>
#include <iostream>
int main() {
std::vector<int> values;
std::ifstream fp("matrices.txt");
for (int value; fp >> value; ) {
values.emplace_back(value);
}
std::cout << "I read " << values.size() << " values:\n";
for (auto && value : values) std::cout << value << " ";
std::cout << "\n";
}
Result:
$ clang++ matrixread.cpp -std=c++17
$ ./a.out
I read 18 values:
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9
You don't increment i, thus always writing to the first element. It should be:
matrix_file >> proto_matrix[i++];

How to format this output C++

I've got a map containing a word and a set of integers as the value.
I want to output the word left aligned and then the integer values in the set in columns that are lined up. I thought that this would work but it seems to output very badly.
How would I go about adjusting this so that the number columns line up with one another and have a decent amount of spaces in between them?
for (auto cbegin = ident_map.begin(); cbegin != ident_map.end(); cbegin++) {
outFile << left << (*cbegin).first << setw(10);
for (set<int>::iterator setITR = (*cbegin).second.begin(); setITR != (*cbegin).second.end(); setITR++) {
outFile << right << *setITR << setw(4);
}
outFile << endl;
}
I think that this should output correctly but it comes out looking like this:
BinarySearchTree 4
Key 4 27
OrderedPair 1 4 8 14
T 4
erase 27
first 7 13
insert 1 4
key 27
kvpair 1 4
map_iterator 1 3 8 14
mitr 3 7 8 13 14
result 4 6 7 13
result2 8 9 14 15
second 6
t 4
value_type 1
Try Boost.Format
Here is a toy example that is similar in spirit to what you want to do. The %|30t| and %|50t| formatters ensure that your numbers are left-justified at the columns 30 and 50 respectively.
#include <iostream>
#include <boost/format.hpp>
int main(int argc, char *argv[]) {
std::cout << "0 1 2 3 4 5 " << std::endl;
std::cout << "012345678901234567890123456789012345678901234567890123456789" << std::endl;
for (int i = 0; i < 10; i++) {
// Set up the format to have 3 variables with vars 2 and 3 at
// columns 30 and 50 respectively.
boost::format fmt("string %1%: %|30t|%2% %|50t|%3%");
// Append values we want to print
fmt = fmt % i;
for (int j = 0; j < 2; j++) {
fmt = fmt % rand();
}
// Write to std::cout
std::cout << fmt << std::endl;
// Or save as a string...
std::string s = fmt.str();
}
return 0;
}
Which when run, produces:
$ ./a.out
0 1 2 3 4 5
012345678901234567890123456789012345678901234567890123456789
string 0: 16807 282475249
string 1: 1622650073 984943658
string 2: 1144108930 470211272
string 3: 101027544 1457850878
string 4: 1458777923 2007237709
string 5: 823564440 1115438165
string 6: 1784484492 74243042
string 7: 114807987 1137522503
string 8: 1441282327 16531729
string 9: 823378840 143542612
How about try using \t instead of setw(). \t is the tab special character. This will do wonders for your formatting as you can just figure out the number of tabs to your first position for each line, then it is as simple as following what format you would like, works great because tab is a uniform size

Sum all integers in a string C++

I have a C++ string in my code that is like:
"1 2 3 4 5 6 7 8"
I know the string is composed of integers separated by a space char. How can I sum them?
I'm quite a C++ newbie and in Java I'd simply do:
String str = "1 2 3 4 5 6 7 8";
int sum = 0;
for (int i = 0; i < str.split(" ").length; i++ {
sum += Integer.parse(str.split(" ")[i];
}
How can I do just like this with my string object in C++?
Some people suggested me stringstream but I still can't understand this object and I need to read the string entirely, getting every single digit within it.
Thanks in advance!
Update: some guys nicely tried to help me but still it's not working. Perhaps because of some quirk of my problem which I haven't clarified before. So here it goes:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
freopen("variable-exercise.in", "r", stdin);
int sum = 0, start = 0;
string line;
while(getline(cin ,line)) {
istringstream iss(line);
while(iss >> start) {
sum += start;
}
cout << start << endl;
sum = start = 0;
}
return 0;
}
Ah, the input file contains the following:
1
3 4
8 1 1
7 2 9 3
1 1 1 1 1
0 1 2 5 6 10
So, for each line, the program must print the sum of all integers in the string line. This example would generate:
1
7
10
21
5
24
thanks
Some people suggested me stringstream but I still can't understand this object and I need to read the string entirely
I guess you were given a good advice. With std::istringstream you could just read in values one after the other as you would read them from the standard input (or any other input stream).
For instance:
#include <sstream>
#include <string>
#include <iostream>
int main()
{
// Suppose at some time you have this string...
std::string s = "1 2 3 4 5 6 7 8 9 10";
// You can create an istringstream object from it...
std::istringstream iss(s);
int i = 0;
int sum = 0;
// And read all values one after the other...
while (iss >> i)
{
// ...of course updating the sum each time
sum += i;
}
std::cout << sum;
}
Like this:
std::stringstream s("1 2 3 4 5 6 7 8 9");
int n = 0;
int x;
while (s >> x)
n += x;
std::cout << n << std::endl;
After your edit:
cout << start << endl;
This is wrong, you should be printing sum instead:
cout << sum << endl;
I used C code to solve this problem. Here's the final solution:
#include <stdio.h>
#include <string.h>
int main() {
char *c;
char line[100];
int x, sum = 0;
while(gets(line)) {
for(c = strtok(line, " "); c ; c = strtok(NULL, " ")) {
sscanf(c, "%d", &x);
sum += x;
}
printf("%d\n", sum);
sum = 0;
}
return 0;
}
Hope it helps anyone who might have the same problem!