matrix from a file input with commas in the file - c++

so my problem is that i have to read from a file that looks like this
input_M1
1,2
9,5
4,1
input_M2
3,2,6,1
4,1,7,8
of course I have to omit the "input_1" and "input_1", and i was able to do that and separate each matrix by itself in a string like this :
1,2
9,5
4,1
and this :
3,2,6.1
4,1,7,8
I was trying to make a dynamic array, i got the rows, with this
while(getline(ss,str1)){
row++;
}
and it prints the number of rows. However, when I do that for the columns :
while(getline(ss,str1,',')){
colmn++;
}
and when I print it out nothing appears.
and here is my whole code :
ifstream inFile;
inFile.open("c:\\Games\\crap.txt");
if (inFile.is_open()){
cout << "File successfully opened" << endl;
}
else{
cout << "Error opening file" << endl;
}
string sMain,sCutOut,firstMatrix,secondMatrix;
int counter = 1;
while(getline(inFile,sMain)){
sCutOut+=(sMain+'\n');
}
//cout << sCutOut << endl;
sCutOut = sCutOut.substr( sCutOut.find("1")+1,sCutOut.length() );
//cout << sCutOut << endl;
firstMatrix = sCutOut.substr( 0,sCutOut.find("input_M2") );
//cout << firstMatrix << endl;
secondMatrix = sCutOut.substr( sCutOut.find("_")+3,sCutOut.length() );
//cout << secondMatrix << endl;
istringstream ss (firstMatrix);
istringstream sn (secondMatrix);
string str1,str2,str3;
int row=0,colmn=0;
while(getline(ss,str1,'\n')){
//cout << str1 << '\n';
row++;
//cout << row << " ";
}
while(getline(ss,str2,',')){
cout << str2 << '\n';
colmn++;
cout << colmn << " ";
}
also, i get this when I try to print out the (firstMatrix) with out the new line I get this :
1,29,54,1

I used C++11 Regular expression library and I applied a simple regular expression to strip off the input_M? lines.
// under g++ 4.8.1 compile:
// $ g++ apply_regex.cpp -std=c++11 -lboost_regex -o apply_regex
#include <fstream>
#include <iostream>
// #include <regex> not implemented yet in g++ 4.8.1 (c++11 standard)
#include <boost/regex.hpp> // using boost libraries
using namespace std;
using boost::regex;
using boost::regex_replace;
int main() {
ifstream inFile;
inFile.open("crap.txt");
if (inFile.is_open()) {
cout << "File successfully opened" << endl;
}
else {
cout << "Error opening file" << endl;
}
string sMain, sCutOut;
while(getline(inFile,sMain)) {
sCutOut+=(sMain+'\n');
}
inFile.close();
cout << "Read lines from crap.txt" << endl;
cout << sCutOut;
// regular expression checks from input_M1 or input_M2 etc..
regex txt_regex("input_M[1-9]+");
string result = regex_replace(sCutOut, txt_regex, "");
cout << "After applying regular expression \"input_M[1-9]+\":" << endl;
cout << result;
return 0;
}
The result of the above code is:
$ ./apply_regex
File successfully opened
Read lines from crap.txt
input_M1
1,2
9,5
4,1
input_M2
3,2,6,1
4,1,7,8
After applying regular expression "input_M[1-9]+":
1,2
9,5
4,1
3,2,6,1
4,1,7,8

Update : i made the matrix into one line and then made them delimited with commas and that is it !
#include<iostream>
#include<fstream>
#include<string>
#include<string.h>
#include<sstream>
#include<vector>
#include<string>
#include<stdlib.h> using namespace std;
int main() {
cout << "Hello! today i'm gonna help you to multiply 2 matrices." << endl;
cout << "But first, we need to discuss the format of the file" << endl;
cout << "help me with the format so i can help you to multiply !" << endl;
cout << "this is how i like the format of the file to be : " << endl;
cout << "--------------------------------" << endl;
cout << "input_M1" << endl;
cout << "number,number," << endl;
cout << "number,number" << endl;
cout << "input_M2" << endl;
cout << "number,number," << endl;
cout << "number,number," << endl;
cout << "--------------------------------" << endl;
cout << "make sure that you put the comma at the end of each line to indicate the end of the line of the matrices [not the input_M1 or input_M2], Have fun !" << endl << endl;
string fileDirct = ""; string fileName = "";
cout << "Now, Enter the file directory, with 2 backslashs, i.e : 'C:\\\\program files'" << endl; cin >> fileDirct; cout << "and Enter the file name, followed by the file type, i.e : 'testData.txt'" << endl; cin >> fileName;
string file = fileDirct+"\\"+fileName; fileDirct = fileDirct.c_str(); ifstream infile;
infile.open(file.c_str());
//ifstream infile( "c:\\Games\\crap.txt");
string sLiner,sStoring,firstMatrix,secondMatrix,sTemp1,sTemp2;
while(infile){
getline( infile, sLiner );
sStoring+=(sLiner+'\n');
}
//cout << sStoring;
sStoring = sStoring.substr( sStoring.find("_")+3,sStoring.length() );
//cout << sStoring;
firstMatrix = sStoring.substr(0,sStoring.find("i"));
//cout << firstMatrix;
secondMatrix = sStoring.substr(sStoring.find("_")+3,sStoring.length());
//cout << secondMatrix;
istringstream ssMtrx1(firstMatrix);
istringstream ssMtrx2(secondMatrix);
istringstream ss(firstMatrix);
istringstream ssk(secondMatrix);
ssMtrx1 >> sTemp1;
istringstream ssR_C1(sTemp1);
int colmn=0;
while(getline(ssR_C1,sTemp2,',')){
colmn++;
}
//cout << colmn;
if (colmn > 6 ){
cout << "the matrix has more than 6 columns";
}
sTemp1.clear();
int row=0;
while(getline(ssMtrx1,sTemp1)){
row++;
}
//cout << row;
if (row > 6 ){
cout << "the matrix has more than 6 rows";
}
//--------------------------------------------------------------------------------
sTemp1.clear();
ssMtrx2 >> sTemp1;
istringstream ssR_C2(sTemp1);
int colmn2=0;
while(getline(ssR_C2,sTemp2,',')){
colmn2++;
}
//cout << colmn2;
if (colmn2 > 6 ){
cout << "the matrix has more than 6 columns";
}
sTemp1.clear();
int row2=0;
while(getline(ssMtrx2,sTemp1)){
row2++;
}
row2 = row2-1;
//cout << row2;
if (row2 > 6 ){
cout << "the matrix has more than 6 rows";
}
//=========================================================================
int** Mtrx1Arry = new int*[row];
for(int i = 0; i < row; ++i){
Mtrx1Arry[i] = new int[colmn];
}
int** Mtrx2Arry = new int*[row2];
for(int i = 0; i < row2; ++i){
Mtrx2Arry[i] = new int[colmn2];
}
sTemp1.clear();
sTemp2.clear();
while(getline(ss,sTemp1,'\n')){
sTemp2+=sTemp1;
}
//cout << sTemp2;
istringstream ss1(sTemp2);
sTemp1.clear();
for(int i = 0; i < row;i++){
for(int j = 0; j < colmn;j++){
getline(ss1,sTemp1,',');
Mtrx1Arry[i][j]=atoi(sTemp1.c_str());
}
}
for(int i = 0; i < row;i++){
for(int j = 0; j < colmn;j++){
//cout << Mtrx1Arry[i][j] << " ";
}
}
//-------------------------------------------------------------
sTemp1.clear();
sTemp2.clear();
while(getline(ssk,sTemp1,'\n')){
sTemp2+=sTemp1;
}
//cout << sTemp2;
istringstream ss2(sTemp2);
sTemp1.clear();
for(int i = 0; i < row2;i++){
for(int j = 0; j < colmn2;j++){
getline(ss2,sTemp1,',');
Mtrx2Arry[i][j]=atoi(sTemp1.c_str());
}
}
for(int i = 0; i < row2;i++){
for(int j = 0; j < colmn2;j++){
//cout << Mtrx2Arry[i][j] << " ";;
}
}
//=============================================================================
// mtrx1[x][y] and mtrx2[z][y] : y has to == z // while the values are under 6
if( (colmn <= 6) && (colmn2 <= 6) && (row <= 6) && (row2 <= 6)){
if (colmn==row2){
cout << "the two matrices can be multiplied " << endl;
cout << "the new matrix will be : " << row << " x " <<colmn2 << endl;
int** MtrxRsltArry = new int*[row];
for(int i = 0; i < row; ++i){
MtrxRsltArry[i] = new int[colmn2];
}
for(int i = 0; i < row;i++){
for(int j = 0; j < colmn2;j++){
MtrxRsltArry[i][j]=0;
for(int k=0; k < colmn; k++){
MtrxRsltArry[i][j]=MtrxRsltArry[i][j]+(Mtrx1Arry[i][k]*Mtrx2Arry[k][j]);
}
}
}
for(int i = 0; i < row;i++){
//cout << endl;
for(int j = 0; j < colmn2;j++){
//cout << MtrxRsltArry[i][j] << ",";;
}
}
// cout << endl;
ofstream outFile;
string cat = fileDirct+"\\result.txt";
outFile.open(cat.c_str());
cout << "the result.txt has been created at : " << fileDirct << endl;
outFile << "result_M";
for(int i = 0; i < row;i++){
outFile << endl;
for(int j = 0; j < colmn2;j++){
outFile << MtrxRsltArry[i][j] << ",";
}
}
}
else{
cout << "the two matrices can not be multiplied ";
}
}
for(int i = 0; i < colmn; ++i) {
delete [] Mtrx1Arry[i];
}
delete [] Mtrx1Arry;
for(int i = 0; i < colmn2; ++i) {
delete [] Mtrx2Arry[i];
}
delete [] Mtrx2Arry;
return 0; }

Related

ofstream not outputting file

I'm trying to output some arrays to a file "output.txt". I run this code with no errors but no output file seems to be created to the working directory
ofstream myfile("output.txt");
if (myfile.is_open()) {
myfile << "t: " << endl;
for (int i = 0; i < range; i++) {
myfile << t[i] << " ";
}
cout << endl;
myfile << "x_1: " << endl;
for (int i = 0; i < range; i++) {
myfile << x_1[i] << " ";
}
cout << endl;
myfile << "y_1: " << endl;
for (int i = 0; i < range; i++) {
myfile << y_1[i] << " ";
}
cout << endl;
myfile << "x_2: " << endl;
for (int i = 0; i < range; i++) {
myfile << x_2[i] << " ";
}
cout << endl;
myfile << "y_2: " << endl;
for (int i = 0; i < range; i++) {
myfile << y_2[i] << " ";
}
cout << endl;
myfile.close();
}
else cout << "Unable to open file";
What's the problem?

How to prevent frequency table to count ''empty boxes'' in c++

I wrote the below code (for homework) that is counting letters and numbers and generates a frequency table.
My question is: how to stop the frequency generation when the letter or number does not exist?
With the code I wrote, the program is counting every letter that are being fed to it but is also publishing a line for every possible letter/number in the ASCII code.
I hope I asked my question right and I appreciate any help or advice!
#include <iostream>
#include <string>
using namespace std;
int countingLetters(string someWords);
int countingNumbers(string someWords);
int frequency(string someWords, double totalChar);
int main() {
string someWords;
cout << "Write a some words: " << endl;
getline(cin, someWords);
cout << "You wrote:" << someWords << '\n';
cout << "Your sentence has " << someWords.length() << " characters." << '\n';
double totalChar = someWords.length();
cout << "Your sentence has " << countingLetters(someWords) << " letters." << '\n';
cout << "Your sentence has " << countingNumbers(someWords) << " numbers." << '\n';
cout << "Frequency of signs and letters :" << endl;
frequency(someWords, totalChar);
return 0;
}
int countingLetters(string someWords) {
int count = 0;
for (int i = 0; i < someWords.length(); i++) {
if (someWords[i] >= 'a' && someWords[i] <= 'z')
count++;
}
return count;
}
int countingNumbers(string someWords) {
int count = 0;
for (int i = 0; i < someWords.length(); i++) {
if (isdigit(someWords[i]) != 0)
count++;
}
return count;
}
int frequency(string someWords, double totalChar) {
cout << " Letter" << '\t' << "Antal" << '\t' << "Procent" << endl;
int frequency[255]={0};
for (int i = 0; i < someWords.length(); i++) {
char c = someWords[i];
if (isdigit(c) != 0)
frequency[c]++;
if (isalpha(c) != 0)
frequency[c]++;
}
for (int i = 0; i < sizeof(frequency); i++) {
if(frequency[i]>0)
cout << '\t' << static_cast<char>(i) << '\t' << frequency[i] << '\t' << frequency[i]/totalChar << endl;
}
return 0;
}
sizeof(frequency) is the size of the frequency array in bytes. You want the number of elements which is the size in bytes if the array divided by the size in bytes of one array element:
This is the number of elements of the frequency array:
sizeof(frequency) / sizeof(frequency[0])
But as you are using C++ you shouln't use raw arrays but std::array:
#include <array>
...
int frequency(string someWords, int totalChar) {
cout << " Letter" << '\t' << "Antal" << '\t' << "Procent" << endl;
std::array<int, 255> frequency{0};
for (int i = 0; i < someWords.length(); i++) {
char c = someWords[i];
if (isdigit(c) != 0)
frequency[c]++;
if (isalpha(c) != 0)
frequency[c]++;
}
int x = frequency.max_size();
for (int i = 0; i < frequency.max_size(); i++) {
if (frequency[i]>0)
cout << '\t' << static_cast<char>(i) << '\t' << frequency[i] << '\t' << frequency[i] / totalChar << endl;
}
return 0;
}
There is still room for improvement.

Nested For - Loops to create multiplication table C++

I've been trying to overcome this problem for a few hours now and I seem to have one approach to the situation. It seems that the use of selection statements worked in creating the table necessary. Although there are formatting issues.
I'd like to know if there was a way to create the same table
using only nested for-loops as mentioned by our professor.
Are the selection statements necessary or can we implement a system of nested for loops to acquire the same results?
The image below is the required table:
But the image below is what I have:
Below is my code:
for (int i = 0; i <= numChoice; ++i)
{
if (i == 0)
{
for (int k = 1; k <= numChoice; ++k)
{
cout << " " << k;
}
cout << "\n";
}
else
{
cout << i << " | ";
for (int j = 1; j <= numChoice; ++j)
{
if (j*i <= 9)
{
cout << " " << j*i << "|";
}
else if (j*i > 9 && j*i <= 100)
{
cout << " " << j*i << "|";
}
else if (j*i > 99 && j*i <= 999)
{
cout << " " << j*i << "|";
}
}
cout << "\n";
for (int k = 0; k <= numChoice; ++k)
{
if (k == 0)
{
cout << "-|";
}
else
{
cout << "----|";
}
}
cout << "\n";
}
}
The following code uses no if else constructs. The formatting can be got by using setw, used for setting the width of integers.Following code produces perfect output.
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int i,j;
cout<<" "<<1;//5 space chars
for(i = 2;i <= 10;++i)
cout<<" "<<i;//4 space chars
cout<<endl;
cout<<" ----|";
for(i = 2;i <= 10;++i)
cout<<"----|";
cout<<endl;
for(i = 1;i <= 10;++i)
{
cout<<setw(2)<<i<<"|";
for(j = 1;j <= 10;++j)
cout<<setw(4)<<j*i<<"|";
cout<<endl;
cout<<" -|----";
for(j = 2;j <= 9;++j)
cout<<"|----";
cout<<"|----|";
cout<<endl;
}
return 0;
}
#FranticCode. I'm also in the same class as you and was having problems with this homework assignment as well. I still don't understand it, but I figured out how to manipulate Sumeet's code to give us correct format. The ONLY thing I am having a problem with now is adding an empty space AFTER the first multiplication table and before the menu redisplay. I'll share what I have and maybe you can figure it out. Still going to ask the professor to review chapter 5 because I would like to learn it rather than just submit the homework.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
char userSelection;
int numForTable;
int col;
int row;
do
{
cout << "MENU" << endl
<< "a) Generate Multiplication Table" << endl
<< "q) Quit the program" << endl
<< "Please make a selection: ";
cin >> userSelection;
if (userSelection == 'a')
{
cout << "Please enter a number for your multiplication table: " << endl;
cin >> numForTable;
while (numForTable < 1 || numForTable > 10)
{
cout << "Please enter a number between 1 & 10." << endl;
cin >> numForTable;
}
cout << "\n"
<< "MULTIPLICATION TABLE: " << numForTable << "'s" << endl
<< "\n"
<< " " << 1;
for (col = 2; col <= numForTable; ++col)
cout << " " << col;
cout << endl;
cout << " ----|";
for (col = 2; col <= numForTable; ++col)
cout << "----|";
cout << endl;
for (col = 1; col <= numForTable; ++col)
{
cout << setw(2) << col << "|";
for (row = 1; row <= numForTable; ++row)
cout << setw(4) << col * row << "|";
cout << endl;
cout << " -|----";
for (row = 2; row <= numForTable - 1; ++row)
cout << "|----";
cout << "|----|";
cout << endl;
}
}
else if (userSelection != 'q')
{
cout << "Invalid Selection\n" << endl;
}
else if (userSelection == 'q')
{
cout << " You have chosen to quit the program. Thank you for using!" << endl;
}
}
while (userSelection != 'q');
//system("PAUSE");
return 0;
}
got curious to see if i could add the lines as easy as i claimed, it took a bit of fiddling, but here's the result (updated code below to also have lines).
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
int counter;
int counter2;
int amount;
cout << " |-----------------------------------------------------------|" << endl; // first line of table.
for(counter=1;counter<11;counter++){ // the 2 for lines create our 2 dimensional table
for(counter2=1;counter2<11;counter2++){
cout << " | " << setw(3) << counter*counter2; // setw(3) is a function of <iomanip>,
//setting minimum width to 3 for numbers.
}
cout << " |" << endl; // this here is being added to the end of each line and starts a new line.
cout << " |-----------------------------------------------------------|" << endl; // this is being inserted between each line, and starts a new line.
}
return 0;
}
Use the following construct:
for (int i=0; i<=numChoice; i++) // display first row of numbers
cout <<"\t" << i << "\t";
cout << "\n";
for (int i=0; i <=numChoice; i++) {
cout << i << "\t";
for (int j=0; j <=numChoice; j++)
cout << i*j << "\t";
cout << "\n";
}

Displaying An Array big elements

I want to display array using a method, if the array has under 200 elements it display all the elements, which works fine for me. The problem is if the array has over 200 elements i want to display the first 100 elements and the last 100 elements of an array. It works if I use an array of 500 elements or even 10000, but I type something like 9999 or 8999 I get long negative integer numbers on the bottom half of my display list but the top half half works. Any advice?
int main()
{
string fileName,text, size;
fstream inText;
int lengthOf = 0;
cout << "Please Enter An Input File Name: ";
getline(cin, fileName);
inText.open(fileName.c_str() , fstream::in);
if(!inText)
{
cout << "Could Not Open " << fileName << " File" << endl;
exit(EXIT_FAILURE);
}
else
{
inText >> lengthOf;
int * myArray = new int[lengthOf];
for(int i = 0; i < lengthOf; i++)
{
inText >> myArray[i];
}
cout << "Data File Array " << endl;
displayArray(myArray,lengthOf);
}
return 0;
}
void displayArray (int a[], int s)
{
if(s <= 200)
{
for (int i = 0; i < s; ++i)
{
if(i%10 == 0)
{
cout << endl;
}
cout << setw(6) << a[i] << " ";
}
cout << endl;
}
else
{
for(int i = 0; i < 100; i++)
{
if(i%10 == 0)
{
cout << endl;
}
cout << setw(6) << a[i] << " ";
}
cout << endl;
for (int i = s-100; i < s; ++i)
{
if (i%10 == 0)
{
cout << endl;
}
cout << setw(6) << a[i] << " ";
}
cout << endl;
}
}
Printing the array is straight forward, example:
int main()
{
int a[551]; //some random number
int s = 551;
for (int i = 0; i < s; ++i) a[i] = i;
for (int i = 0; i < s; ++i)
{
if (i % 10 == 0) cout << "\n";
if (i % 100 == 0) cout << "\n";
cout << std::setw(6) << a[i] << " ";
}
return 0;
}
When reading the file you can use std::vector to store the integers, this way you don't have to know how big the array should be before hand. The example below reads text and then tries to convert to integer, this way you know if there was an error in input file.
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iomanip>
using namespace std;
int main()
{
std::string fileName;
cout << "Please Enter An Input File Name: ";
getline(cin, fileName);
std::ifstream inText(fileName);
std::vector<int> vec;
std::string temp;
while (inText >> temp)
{
try {
int i = std::stoi(temp);
vec.push_back(i);
}
catch (...) {
cout << temp << " - error reading integer\n";
}
}
for (size_t i = 0; i < vec.size(); ++i)
{
if (i % 10 == 0) cout << "\n";
if (i % 100 == 0) cout << "\n";
cout << std::setw(6) << vec[i] << " ";
}
return 0;
}
Are You sure the problem is with this method? The code seems to work, I can't reproduce Your problem. Maybe You could paste Your whole code (if its not too big)?

Reading from an input file

#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[]) {
int size = 0;
int highNum = 0;
int m;
string fname;
cout << "Supply the name of the input file you would like to use." << endl;
cin >> fname;
ifstream input;
input.open(fname.c_str());
input >> size;
int numbers[size];
for (int n = 0; n < size; n++)
input >> numbers[n];
for (m = 0 ; m < size ; m++)
{
if (numbers[m] > highNum)
highNum = numbers[m];
}
int j;
int k;
bool values[] = {false, false, false, false, false, false};
for (j = highNum; j > 0 ; j--)
{
for (k = size - 1 ; k >= 0 ; k--)
{
if (j <= numbers[k])
values[k] = true;
}
if (values[0])
cout << "| xxx";
else
cout << "| ";
if (values[1])
cout << " +++";
else
cout << " ";
if (values[2])
cout << " ***";
else
cout << " ";
if (values[3])
cout << " ---";
else
cout << " ";
if (values[4])
cout << " +++";
else
cout << " ";
if (values[5])
cout << " +++" << endl;
else
cout << " " << endl;
}
return 0;
}
I am trying to write a code to print a bar chart by reading integers from a separate text file. I posted the complete code, but I know the bottom half works if you just input numbers. I was wondering what the problem with this is given that there is a data file in the same directory. When I run this program and enter the name of the data file i created to test it, the program runs, but no graph is produced.
Your program works for me. I suppose your input file isn't present in the current working directory of your process. I suggest you add a check to see if input is valid after the call to open.