convert an array string to intger c++ (beginner) - c++

I have a text file which that contains only numbers inside , and i have successfully pulled the numbers from the file and stored it inside an array:
my problem is that the array is "string" and i cant do mathematical operations on the array like Addition and Subtraction
I have tried to use atoi(array[i][j].c_str()) to convert it to intger
but it gives me only the first digit of a number!
my program looks like this for now , its a mess I know :(
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
ifstream iFile("input.txt");
string line;
string array[7][7];
for (int i=0;i<7;i++){
for (int j=0;j<6;j++){
getline(iFile,line);
if (!line.empty()){
array[i][j]=line;
}
else {
break;
}
}
}
cout<<"number of processes is: "<<array[0][0]<<endl;
cout<<"resource types: "<<array[1][0]<<endl<<endl;
cout<<"Allocation Matrix:"<<endl;
cout<<" A B C D"<<endl;
cout<<"0: "<<array[2][0]<<endl;
cout<<"1: "<<array[2][1]<<endl;
cout<<"2: "<<array[2][2]<<endl;
cout<<"3: "<<array[2][3]<<endl;
cout<<"4: "<<array[2][4]<<endl;
cout<<"Max Matrix:"<<endl;
cout<<" A B C D"<<endl;
cout<<"0: "<<array[3][0]<<endl;
cout<<"1: "<<array[3][1]<<endl;
cout<<"2: "<<array[3][2]<<endl;
cout<<"3: "<<array[3][3]<<endl;
cout<<"4: "<<array[3][4]<<endl;
cout<<"Need Matrix:"<<endl;
cout<<" A B C D"<<endl;
//cout<<"0: "<<array[3][1]+array[2][1]<<endl;
//int c= atoi(array[3][1].c_str());
//int c2= atoi(array[3][1].c_str());
//cout<<c+c2<<endl;
return 0;
}
my input.txt file looks like this:
5
4
0 0 1 2
1 0 0 0
1 3 5 4
0 6 3 2
0 0 1 4
0 0 1 2
1 7 5 0
2 3 5 6
0 6 5 2
0 6 5 6
1 5 2 0
1:0 4 2 0
edit:
note:if there is an empty line >> stop!
the program is based on banker algorithm which takes the first number from the input.txt as the numbers of of processes
then takes the second number as the numbers of of resource types
then takes the next numbers that there is no empty line between them as Allocation Matrix
then takes the next numbers that there is no empty line between them as max Matrix
and here is my problem when i want do Subtraction between Allocation Matrix and max Matrix because both are strings !
as for 1:0 4 2 0 it means do some operations with process number 1

You can use atoi but in c++ you have better options.
in c++ you can easily use stringstream to convert these types.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int convert_str_to_int(const string& str) {
int val;
stringstream ss;
ss << str;
ss >> val;
return val;
}
int main () {
string str = "1024";
int val = convert_str_to_int(str);
cout << "Val is: " << val << ", val/2 is " << val/2 << endl;
}

Related

Reading each line from a text file, word by word and converting to int (Infinite loop or crashing?)

I'm trying to read in this text file:
8 4 4 6 1
8 4 4 6 2
8 4 4 6 3
8 4 4 6 4
8 4 4 6 5
8 4 4 6 6
8 4 4 6 7
8 4 4 6 8
11 4 4 6 3
15 11 13
7 2 1 4 4
9 4 3 9 9
8 2 1 5 4
10 1 2 3 4 6 1
6 1 1 2 5 3 2
13 1 1 2 10 3 8
11 2 11 10 7
And printing it exactly as shown to the console (to make sure I got every input).
However, for some reason my code crashes after reading in the first line. I can't even terminate the debugger.
Here's my code:
while(getline(inFile, buffer)){
buffer2 = strdup(buffer.c_str());
line = strtok(buffer2, " ");
size = atoi(line);
cout << size << " ";
while(line!=NULL){
line = strtok(NULL, " ");
cout << line << " ";
}
cout << "~~~~~~~~~" << endl;
}
If you are going to use C++ you should take advantage of that, use string streams:
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std; //for sample purposes, should not be used
int main() {
int temp, count = 0, sum = 0, total = 0;
string buffer;
ifstream myFile("in.txt");
if (!myFile.is_open())
cout << "No file" << endl;
else{
while(getline(myFile, buffer)){
sum = 0;
stringstream ss(buffer);
while(ss >> temp){
count++; //number count
sum += temp; //line sum
cout << temp << " ";
}
total += sum; //total sum
cout << endl << "count: " << count << endl
<< "sum: " << sum << endl << "total: " << total << endl << endl;
}
myFile.close();
}
cout << "~~~~~~~~~" << endl;
}
You are leaking the memory allocated by strdup(). You need to call free() when you are done using buffer2.
But more importantly, strtok() returns NULL when there are no more tokens to return. But it is undefined behavior to pass a NULL char* pointer to operator<<. Your while loop is doing exactly that when it reaches the end of each line, so anything could happen, including crashing.
Try this instead:
while (getline(inFile, buffer)) {
buffer2 = strdup(buffer.c_str());
if (buffer2 != NULL) {
line = strtok(buffer2, " ");
while (line != NULL) {
size = atoi(line);
cout << size << " ";
line = strtok(NULL, " ");
}
free(buffer2);
}
cout << "~~~~~~~~~" << endl;
}
That being said, why are you using strdup(), strtok(), and atoi() at all? You are writing C++ code, you should C++ semantics instead of C semantics. For example, you can use std::istringstream instead, eg:
while (getline(inFile, buffer)) {
istringstream iss(buffer);
while (iss >> size) {
cout << size << " ";
}
cout << "~~~~~~~~~" << endl;
}
As always, there are many possible solutions. I would like to show an additional one. This is using more modern C++ elements, mainly from the algorithm and iterator library.
So, what will we do?
First we read each line as a std::string in a simple for loop with std::getline. Then we will put the line again in a std::istringstream so that we can take advantage of C++ iterator: std::istream_iterator.
This iterator will iterate over the elements in the string and extract all integers. It is like calling the extractor operator ( >> ) for all elements in the line string.
We use the iterator in the so called range constructor of os a std::vector. This inplace created vector, will be added to the destiantion data. So, as a result, we will get vector of vector of int: A 2-dimensional vector.
For debug purposes, we copy each row of intes to std::cout.
Please note that we do really need only very few and very simple statements to fulfill the task.
Please check.
#include <iostream>
#include <string>
#include <algorithm>
#include <sstream>
#include <vector>
#include <iterator>
std::istringstream sourceFile{R"(8 4 4 6 1
8 4 4 6 2
8 4 4 6 3
8 4 4 6 4
8 4 4 6 5
8 4 4 6 6
8 4 4 6 7
8 4 4 6 8
11 4 4 6 3
15 11 13
7 2 1 4 4
9 4 3 9 9
8 2 1 5 4
10 1 2 3 4 6 1
6 1 1 2 5 3 2
13 1 1 2 10 3 8
11 2 11 10 7)"};
int main()
{
// Here we will store the resulting int values
std::vector<std::vector<int>> data{};
for (std::string line{}; std::getline(sourceFile, line); ) {
// Split the line into integers and add to target array
std::istringstream iss(line);
data.emplace_back(std::vector<int>(std::istream_iterator<int>(iss), {}));
}
// Now all data is in our vector of vector of int
// Show read data on screen
std::for_each(data.begin(), data.end(), [](const std::vector<int>& v){
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ")); std::cout << "\n";});
return 0;
}
Please note. I do not have files on SO. So I used a std::istringstream as input stream. You may of course exchange it with any other std::ftream

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 can I write output to text file in C++ by script

I written a code to create two random number with a given range. I want to write the output result (two random numbers). In script file, I want to write the output in same line for each iteration as my expected result
My current output is
1 0
1 0
2 1
2 3
0 0 //output of second iteration
1 1
2 2
1 3
My expected result is
1 0 0 0
1 0 1 1
2 1 2 2
2 3 1 3
This is my full code
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <time.h> /* time */
#define random(x) (rand()%x)
int main(int argc, char **argv) {
unsigned int time_ui = static_cast<unsigned int>( time(NULL) );
srand( time_ui );
int number1;
int number2;
int range=atoi(argv[1]);
number1 = random(range);
number2 = random(range);
//std::cout<< number1 << "\t" <<number2;
std::ofstream myfile;
myfile.open ("report.txt", std::ios::app);
myfile << number1 << "\t" <<number2<<'\n';
myfile.close();
return 0;
}
My script file is
#!/bin/bash
a=1
iter=0
for ((iter; iter <= 1; iter++))
do
a=1
while [ $a -lt 4]
do
./random_num $a
a=`expr $a + 1`
done
done
Note that there is a newline character that you output in your C++ code, which makes it nearly impossible to "unoutput". I would suggest moving the logic from the bash into the C++ code or vice versa. C++ has options such has setfill which can help you control this.

Print all partitions of a given number

The task is to write a C++ recursive function, that receives an integer and prints all of it partitions. (with importance to order)
Examples:
n=1 the only permutation is {1}
n=2 the permutations are {1,1},{2}
n=3 the permutations are {1,1,1},{1,2},{2,1},{3}
n=4 the permutations are {1,1,1,1},{1,1,2},{1,2,1},{1,3},{2,1,1},{2,2},{3,1},{4}
note the importance for order, for example for n=3 both {1,2} and {2,1} are different and valid answers.
Here is my solution which contains a bug that I'm having a hard time to trace:
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
using namespace std;
stringstream g_ss_str("");
void printSums(int n){
static stack<string> strings;
if (n==0){
cout<<g_ss_str.str()<<endl;
return;
}
for (int i=1; i<=n; ++i){
g_ss_str<<i<<" ";
strings.push(g_ss_str.str());
printSums(n-i);
if (!strings.empty()) {
g_ss_str.str(strings.top());
strings.pop();
}
}
}
The problem starts with n=3, in that case the output I get is:
1 1 1
2 1
2 1
3
Instead of:
1 1 1
1 2
2 1
3
Appreciate your help!
You are playing some unnecessarily complicated games with your stringstream and your stack. Try something like this:
void printSumsHelper(int n, const string& prefix) {
if (n==0){
cout << prefix << endl;
return;
}
for (int i=1; i<=n; ++i) {
ostringstream ss;
ss << prefix << i << ' ';
printSumsHelper(n - i, ss.str());
}
}
void printSums(int n){
printSumsHelper(n, "");
}

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!