This is my code.
#include <iostream>
using namespace std;
typedef struct
{
int polski;
int wf;
int matma;
}oceny;
int funkcja_liczaca(int suma, int ile_liczb, int ktory_przedmiot, oceny &temporary);
int main()
{
int suma = 0;
int temp[3];
int ile_liczb_zostalo_wprowadzonych = 0;
oceny database;
string teksty[3] = {"polski: ", "wf: ", "matma: "};
for (int i=0; i!=3; i++)
{
cout << teksty[i] << endl;
while(temp[i]!=0)
{
cin >> temp[i];
if(cin.good()) //floating point exception here. the code don't even step into this one.
{
{
suma = temp[i] + suma;
ile_liczb_zostalo_wprowadzonych++;
if(temp[i]==0){ile_liczb_zostalo_wprowadzonych--;}
}
}else cout << "error";
};
funkcja_liczaca(suma, ile_liczb_zostalo_wprowadzonych, i, database);
suma = 0;
ile_liczb_zostalo_wprowadzonych = 0;
}
cout << "output of struct members in main() \n";
cout << database.polski << endl;
cout << database.wf << endl;
cout << database.matma << endl;
return 0;
}
int funkcja_liczaca(int suma, int ile_liczb, int ktory_przedmiot, oceny &temporary)
{
if(ktory_przedmiot==0){temporary.polski=suma/ile_liczb;cout << temporary.polski << endl;}
if(ktory_przedmiot==1){temporary.wf=suma/ile_liczb;cout << temporary.wf << endl;}
if(ktory_przedmiot==2){temporary.matma=suma/ile_liczb;cout << temporary.matma << endl;}
}
It counts arithmetic average of inputed numbers untill user input 0 which ends loop. then the arithmetic average of thoose numbers is counted in the funkcja_liczaca() and it's saved into the members of struct oceny.
everything works fine but i want to implement something like "stream" check while inputing from keyboard to prevent inputing bad variables into integer type variable.
so inputing 'g' into temp[i] is causing floating point exception. the question is why? cin.good() and cin.fail() is not working.
When you want to deal with errors in the input stream, it's better to read the input line by line as a string and then attempt to extract your data from the string. If extraction of the data from the string is successful, proceed to process the data. Otherwise, attempt to read the next line of text. Here's the core logic for that.
while ( true )
{
cout << teksty[i] << endl;
std::string line;
if ( !getline(cin, line) )
{
// Problem reading a line of text.
// Exit.
exit(EXIT_FAILURE);
}
// Construct a istringstream object to extract the data.
std::istringstream istr(line);
if ( istr >> temp[i] )
{
// Extracting the number was successful.
// Add any additional checks as necessary.
// Break out of the while loop.
break.
}
// Bad input. Continue to the next iteration of the loop
// and read the next line of text.
}
I'm trying to use strcpy_s, but I'm having this error:
Unhandled Exception...
struct Item {
//Item's
int code; // Code
char* name[20];
int amount; //Amount in stock
int minAmount; //Minimum amount
float price; //Price
};
The important lines are the beginning and the line with the "#########" beside it. (spot = 0, name string was received, store was initialized in main()).
//add an item to store
void addItem(Item* store, int maxItems, int &numItems)
{
if (maxItems == numItems)
{
cout << "ERROR \n";
return;
}
int spot = numItems; // our item's spot in store[]
int code; // inputted code
//Item's attributes' input
cout << "enter code : \n"; //code
cin >> code;
store[spot].code = code; //Code
cout << "enter name : \n"; //Name
_flushall();
char* name = new char[20];
gets_s(name, 20);
numItems++; //forward the number of items
strcpy_s(*store[spot].name, 20, name); //Name UNHANDLED EXCEPTION ############################
cout << "enter amount : \n"; //Amount in stock
do
{
cin >> store[spot].amount;
if (store[spot].amount < 0) //not negative
cout << "ERROR \n";
} while (store[spot].amount < 0);
cout << "enter minimum amount : \n"; //Minimum amount for orders
do
{
cin >> store[spot].minAmount;
if (store[spot].minAmount < 0) //not negative
cout << "ERROR \n";
} while (store[spot].minAmount < 0);
cout << "enter price : \n"; //Price
do
{
cin >> store[spot].price;
if (store[spot].price < 0) //not negative
cout << "ERROR \n";
} while (store[spot].price < 0);
}
I would advice you to test calling strcpy_s and every other suspicious part of the code separately and see it there is any problem, if there is, work around it and then insert it in the addItem function.
From is visible in the posted code, you seem to be passing a pointer variable with the dereference operator in front of it in most of the functions you use, for example the signature of strncpy_s() is:
errno_t strncpy_s(char *restrict dest,
rsize_t destsz,
const char *restrict src,
rsize_t count);
You need to pass the first parameter without the * as it is a pointer: Item* store, i.e. as pass it as: store[spot].name.
Check this article about pointer assignment, which will help you understand how to pass a pointer as an argument to a function.
Edit after a comment
Your second error message could be because the member name of store is not a pointer, you probably need to pass it using & operator, i.e. pass its address:
strcpy_s(&store[spot].name, 20, name);
I'm trying to processes values from two text files.One holds a set of chars and the other holds a set of integers.each in their respective places in the text file will amount to one test case.For example the first value that is read in each text file is 1 test case.The values are then used to be checked for variability then Which will then be used as variables through out my code.then in the end prints out a double. The issue is I do not know how to reach that second iteration of test cases. All my code does is read the first values of each text file and prints out the double i need but for only the first test case. As i was typing this out i thought of maybe deleting the values once they are done being used then rerunning the program by having my main in a for loop? suggestions?
#include <iostream>
#include <fstream>
using namespace std;
//function prototypes
char getPackage();
bool vaildPackage(char);
int getHours();
bool validHours(int);
double calculatePakg_A(int);
double calculatePakg_B(int);
double calculatePakg_C(int);
void showBill(double);
int main()
{
char Package = getPackage();
int Hours = getHours();
double bill;
switch (Package)
{
case 'A':bill = calculatePakg_A(Hours);
cout << bill << endl;
break;
case 'B':bill = calculatePakg_B(Hours);
cout << bill << endl;
break;
case 'C':bill = calculatePakg_C(Hours);
cout << bill << endl;
break;
case 'a':bill = calculatePakg_A(Hours);
cout << bill << endl;
break;
case 'b':bill = calculatePakg_B(Hours);
cout << bill << endl;
break;
case 'c':bill = calculatePakg_C(Hours);
cout << bill << endl;
break;
default: cout << "you did not enter a valid Service Plan. \n";
break;
}
return 0;
}
char getPackage()
{
ifstream inputFile;
char a;
inputFile.open("Packages.txt");
do
{
inputFile >> a;
} while (! vaildPackage(a));
return a;
}
bool vaildPackage(char a)
{
return a == 'a' || a == 'A'|| a == 'B' || a == 'b'|| a == 'C' || a == 'c';
}
int getHours()
{
ifstream inFile;
int n;
inFile.open("Hours.txt");
do
{
inFile >> n;
} while (! validHours(n));
return n;
}
bool validHours(int n)
{
return n>=0 && n<= 720;
}
double calculatePakg_A(int hrs)
{
if(hrs <=50)
{
return 15.00;
}
else
{
return (hrs-50) * 2.00 + 15;
}
}
double calculatePakg_B(int hrs)
{
if(hrs <=100)
{
return 20.00;
}
else
{
return (hrs-100) * 1.50 + 20.00;
}
}
double calculatePakg_C(int hrs)
{
if(hrs <=150)
{
return 25.00;
}
else
{
return (hrs-150) * 1.00 + 25.00;
}
}
Package.txt
A a B b C c e c
Hours.txt
50 51 100 101 149 251 750 722
As I'm sure you know, you can read multiple fields from a stream:
ifstream inputFile;
char a;
inputFile.open("Packages.txt");
inputFile >> a;
cout << a << endl;
inputFile >> a;
cout << a << endl;
The reason your code doesn't work is that when control returns from getPackage(), the variable inputFile is deleted, so every time you call that function, it opens the file anew and starts reading from the beginning.
One solution is to make the input stream a static variable, so that it will not be deleted, but will maintain its state from one call to the next:
char getPackage()
{
static ifstream inputFile("Packages.txt");
char a;
inputFile >> a;
return a;
}
I think the only issue here is this.
In the function getPackage()
inputFile.open("Packages.txt");
This opens the file every time you call this function
Due to this, this function is reading the first entry (only) every time.
The same issue with getHours function.
One way out is you can read all entries from the file once into a data structure, say vector and iterate through the vector in the main function.
Another way is open the file(s) in main function and introduce a loop in main that calls these functions. Every time they are called, they would return the next entry from the file. This requires passing the opened file ifstream & as an argument to functions getHours and getPackage
I have about 25 millions of integers separated by lines in my text file. My first task is to take those integers and sort them. I have actually achieved to read the integers and put them into an array (since my sorting function takes an unsorted array as an argument). However, this reading the integers from a file is a very long and an expensive process. I have searched many other solutions to get the cheaper and efficient way of doing this but I was not able to find one that tackles with such sizes. Therefore, what would your suggestion be to read the integers from the huge (about 260MB) text file. And also how can I get the number of lines efficiently for the same problem.
ifstream myFile("input.txt");
int currentNumber;
int nItems = 25000000;
int *arr = (int*) malloc(nItems*sizeof(*arr));
int i = 0;
while (myFile >> currentNumber)
{
arr[i++] = currentNumber;
}
This is just how I get the integers from the text file. It is not that complicated. I assumed the number of lines are fixed (actually it is fixed)
By the way, it is not too slow of course. It completes reading in approximately 9 seconds in OS X with 2.2GHz i7 processor. But I feel it could be much better.
Most likely, any optimisation on this is likely to have rather little effect. On my machine, the limiting factor for reading large files is the disk transfer speed. Yes, improving the read speed can improve it a little bit, but most likely, you won't get very much from that.
I found in a previous test [I'll see if I can find the answer with that in it - I couldn't find the source in my "experiment code for SO" directory] that the fastest way is to load the file using mmap. But it's only marginally faster than using ifstream.
Edit: my home-made benchmark for reading a file in a few different ways.
getline while reading a file vs reading whole file and then splitting based on newline character
As per usual, benchmarks measure what the benchmark measures, and small changes to either the environment or the way the code is written can sometimes make a big difference.
Edit:
Here are a few implementations of "read a number from a file and store it in a vector":
#include <iostream>
#include <fstream>
#include <vector>
#include <sys/time.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
using namespace std;
const char *file_name = "lots_of_numbers.txt";
void func1()
{
vector<int> v;
int num;
ifstream fin(file_name);
while( fin >> num )
{
v.push_back(num);
}
cout << "Number of values read " << v.size() << endl;
}
void func2()
{
vector<int> v;
v.reserve(42336000);
int num;
ifstream fin(file_name);
while( fin >> num )
{
v.push_back(num);
}
cout << "Number of values read " << v.size() << endl;
}
void func3()
{
int *v = new int[42336000];
int num;
ifstream fin(file_name);
int i = 0;
while( fin >> num )
{
v[i++] = num;
}
cout << "Number of values read " << i << endl;
delete [] v;
}
void func4()
{
int *v = new int[42336000];
FILE *f = fopen(file_name, "r");
int num;
int i = 0;
while(fscanf(f, "%d", &num) == 1)
{
v[i++] = num;
}
cout << "Number of values read " << i << endl;
fclose(f);
delete [] v;
}
void func5()
{
int *v = new int[42336000];
int num = 0;
ifstream fin(file_name);
char buffer[8192];
int i = 0;
int bytes = 0;
char *p;
int hasnum = 0;
int eof = 0;
while(!eof)
{
fin.read(buffer, sizeof(buffer));
p = buffer;
bytes = 8192;
while(bytes > 0)
{
if (*p == 26) // End of file marker...
{
eof = 1;
break;
}
if (*p == '\n' || *p == ' ')
{
if (hasnum)
v[i++] = num;
num = 0;
p++;
bytes--;
hasnum = 0;
}
else if (*p >= '0' && *p <= '9')
{
hasnum = 1;
num *= 10;
num += *p-'0';
p++;
bytes--;
}
else
{
cout << "Error..." << endl;
exit(1);
}
}
memset(buffer, 26, sizeof(buffer)); // To detect end of files.
}
cout << "Number of values read " << i << endl;
delete [] v;
}
void func6()
{
int *v = new int[42336000];
int num = 0;
FILE *f = fopen(file_name, "r");
char buffer[8192];
int i = 0;
int bytes = 0;
char *p;
int hasnum = 0;
int eof = 0;
while(!eof)
{
fread(buffer, 1, sizeof(buffer), f);
p = buffer;
bytes = 8192;
while(bytes > 0)
{
if (*p == 26) // End of file marker...
{
eof = 1;
break;
}
if (*p == '\n' || *p == ' ')
{
if (hasnum)
v[i++] = num;
num = 0;
p++;
bytes--;
hasnum = 0;
}
else if (*p >= '0' && *p <= '9')
{
hasnum = 1;
num *= 10;
num += *p-'0';
p++;
bytes--;
}
else
{
cout << "Error..." << endl;
exit(1);
}
}
memset(buffer, 26, sizeof(buffer)); // To detect end of files.
}
fclose(f);
cout << "Number of values read " << i << endl;
delete [] v;
}
void func7()
{
int *v = new int[42336000];
int num = 0;
FILE *f = fopen(file_name, "r");
int ch;
int i = 0;
int hasnum = 0;
while((ch = fgetc(f)) != EOF)
{
if (ch == '\n' || ch == ' ')
{
if (hasnum)
v[i++] = num;
num = 0;
hasnum = 0;
}
else if (ch >= '0' && ch <= '9')
{
hasnum = 1;
num *= 10;
num += ch-'0';
}
else
{
cout << "Error..." << endl;
exit(1);
}
}
fclose(f);
cout << "Number of values read " << i << endl;
delete [] v;
}
void func8()
{
int *v = new int[42336000];
int num = 0;
int f = open(file_name, O_RDONLY);
off_t size = lseek(f, 0, SEEK_END);
char *buffer = (char *)mmap(NULL, size, PROT_READ, MAP_PRIVATE, f, 0);
int i = 0;
int hasnum = 0;
int bytes = size;
char *p = buffer;
while(bytes > 0)
{
if (*p == '\n' || *p == ' ')
{
if (hasnum)
v[i++] = num;
num = 0;
p++;
bytes--;
hasnum = 0;
}
else if (*p >= '0' && *p <= '9')
{
hasnum = 1;
num *= 10;
num += *p-'0';
p++;
bytes--;
}
else
{
cout << "Error..." << endl;
exit(1);
}
}
close(f);
munmap(buffer, size);
cout << "Number of values read " << i << endl;
delete [] v;
}
struct bm
{
void (*f)();
const char *name;
};
#define BM(f) { f, #f }
bm b[] =
{
BM(func1),
BM(func2),
BM(func3),
BM(func4),
BM(func5),
BM(func6),
BM(func7),
BM(func8),
};
double time_to_double(timeval *t)
{
return (t->tv_sec + (t->tv_usec/1000000.0)) * 1000.0;
}
double time_diff(timeval *t1, timeval *t2)
{
return time_to_double(t2) - time_to_double(t1);
}
int main()
{
for(int i = 0; i < sizeof(b) / sizeof(b[0]); i++)
{
timeval t1, t2;
gettimeofday(&t1, NULL);
b[i].f();
gettimeofday(&t2, NULL);
cout << b[i].name << ": " << time_diff(&t1, &t2) << "ms" << endl;
}
for(int i = sizeof(b) / sizeof(b[0])-1; i >= 0; i--)
{
timeval t1, t2;
gettimeofday(&t1, NULL);
b[i].f();
gettimeofday(&t2, NULL);
cout << b[i].name << ": " << time_diff(&t1, &t2) << "ms" << endl;
}
}
Results (two consecutive runs, forwards and backwards to avoid file-caching benefits):
Number of values read 42336000
func1: 6068.53ms
Number of values read 42336000
func2: 6421.47ms
Number of values read 42336000
func3: 5756.63ms
Number of values read 42336000
func4: 6947.56ms
Number of values read 42336000
func5: 941.081ms
Number of values read 42336000
func6: 962.831ms
Number of values read 42336000
func7: 2572.4ms
Number of values read 42336000
func8: 816.59ms
Number of values read 42336000
func8: 815.528ms
Number of values read 42336000
func7: 2578.6ms
Number of values read 42336000
func6: 948.185ms
Number of values read 42336000
func5: 932.139ms
Number of values read 42336000
func4: 6988.8ms
Number of values read 42336000
func3: 5750.03ms
Number of values read 42336000
func2: 6380.36ms
Number of values read 42336000
func1: 6050.45ms
In summary, as someone pointed out in the comments, the actual parsing of integers is quite a substantial part of the whole time, so reading the file isn't quite as critical as I first made out. Even a very naive way of reading the file (using fgetc() beats the ifstream operator>> for integers.
As can be seen, using mmap to load the file is slightly faster than reading the file via fstream, but only marginally so.
You can use external sorting to sort values in your file without loading them all into memory. Sorting speed will be limited by your hard drive capabilities, but you will be able to mess with really huge files. Here is the implementation.
Try reading blocks of integers and parsing those blocks instead of reading line by line.
260MB is not that big. You should be able to load the whole thing into memory and then parse through it. Once in you can use a nested loop to read the integers between line endings and convert using the usual functions. I'd try and preallocate sufficient memory for your array of integers before you start.
Oh, and you may find the crude old C-style file access functions are the faster options for things like this.
I would do it this way :
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
fstream file;
string line;
int intValue;
int lineCount = 0;
try {
file.open("myFile.txt", ios_base::in); // Open to read
while(getline(file, line)) {
lineCount++;
try {
intValue = stoi(line);
// Do something with your value
cout << "Value for line " << lineCount << " : " << intValue << endl;
} catch (const exception& e) {
cerr << "Failed to convert line " << lineCount << " to an int : " << e.what() << endl;
}
}
} catch (const exception& e) {
cerr << e.what() << endl;
if (file.is_open()) {
file.close();
}
}
cout << "Line count : " << lineCount << endl;
system("PAUSE");
}
It will be pretty straightforward with Qt:
QFile file("h:/1.txt");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
QVector<int> ints;
ints.reserve(25000000);
while (!in.atEnd()) {
int integer;
qint8 line;
in >> integer >> line; // read an int into integer, a char into line
ints.append(integer); // append the integer to the vector
}
At the end, you have the ints QVector you can easily sort. The number of lines is the same as the size of the vector, provided the file was properly formatted.
On my machine, i7 3770k #4.2 Ghz, it takes about 490 milliseconds to read 25 million ints and put them into a vector. Reading from a regular mechanical HDD, not SSD.
Buffering the entire file into memory didn't help all that much, time dropped to 420 msec.
You don't say how you are reading the values, so it's hard to
say. Still, there are really only two solutions: `someIStream
anIntandfscanf( someFd, "%d", &anInt )` Logically, these
should have similar performance, but implementations vary; it
might be worth trying and measuring both.
Another thing to check is how you're storing them. If you know
you have about 25 million, doing a reserve of 30 million on
the std::vector before reading them would probably help. It
might also be cheaper to construct the vector with 30 million
elements, then trim it when you've seen the end, rather than
using push_back.
Finally, you might consider writing a immapstreambuf, and
using that to mmap the input, and read it directly from the
mapped memory. Or even iterating over it manually, calling
strtol (but that's a lot more work); all of the streaming
solutions probably end up calling strtol, or something
similar, but doing significant work around the call first.
EDIT:
FWIW, I did some very quick tests on my home machine (a fairly
recent LeNova, running Linux), and the results surprised me:
As a reference, I did the trivial, naïve implementation, using
std::cin >> tmp and v.push_back( tmp );, with no attempts to
optimize. On my system, this ran in just under 10 seconds.
Simple optimizations, such as using reserve on the vector,
or initially creating the vector with a size of 25000000, didn't
change much—the time was still over 9 seconds.
Using a very simple mmapstreambuf, the time dropped to
around 3 seconds—with the simplest loop, no reserve,
etc.
Using fscanf, the time dropped to just under 3 seconds. I
suspect that the Linux implementation of FILE* also uses
mmap (and std::filebuf doesn't).
Finally, using a mmapbuffer, iterating with two char*, and
using stdtol to convert, the time dropped to under a second,
These tests were done very quickly (less than an hour to write
and run all of them), and are far from rigorous (and of course,
don't tell you anything about other environments), but the
differences surprised me. I didn't expect as much difference.
One possible solution would be dividing the large file into smaller chunks. Sort each chunk separately and then merge all the sorted chunks one by one.
EDIT:
Apparently this is a well-established method. See 'External merge sort' at http://en.wikipedia.org/wiki/External_sorting
I present to you all a program I'm working on for my college programming course. I still have a little ways to go before it completely meets my assignment's requirements, but I've gotten a basic draft of the program error-free (supposedly) and it appears to run… but then it suddenly kicks me into Xcode's debugger and gives me:
Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)
Here's the command line output, up until it kicks me out:
-----------------------
Quarterly_sales_taxator
-----------------------
How many company divisions will we be dealing with? 2
Am I correct in assuming that there are 4 sales quarters? yes
Please enter the sales Company Division #1 brought in for Sales Quarter #1 20
(lldb)
Here's my code:
//
// quarterly_sales_taxator.cpp
// Ch. 7 program #7
//
// Created by John Doe on 11/27/12.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
void read_company_divisions_and_sales_quarters(double **, int, int);
//void write_company_divisions_and_sales_quarters_to_array(double **, int, int); // This will be used later on to read data from a file.
void display_quarterly_sales_array(double **, int, int);
string temp; // A global temporary placeholder variable; I use this several times.
int main()
{
int COMPANY_DIVISIONS,
SALES_QUARTERS = 4;
double **quarterly_sales_form;
cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";
cout << "\nHow many company divisions will we be dealing with? ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
{
cout << "\n\n------"
<< "\nError:"
<< "\n------"
<< "\n\nYou have entered an invalid choice."
<< "\nPlease type a number greater than zero. ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
}
cout << "\n\nAm I correct in assuming that there are 4 sales quarters? ";
getline(cin, temp);
// Convert to uppercase.
for (int count = 0; count < temp.length(); count ++)
{
temp[count] = toupper(temp[count]);
}
if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
{
cout << "\nOk, then how many sales quarters are we dealing with? ";
getline(cin, temp);
stringstream(temp)>>SALES_QUARTERS;
}
cout << endl << endl;
// This sets up the 2d array.
quarterly_sales_form = new double *[COMPANY_DIVISIONS];
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS); // I'll add this feature later.
cout << "\n\nHere's what you entered:\n\n";
display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// Since we used a series of pointers, we need to free the allocated space back up.
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ delete[] quarterly_sales_form[COMPANY_DIVISIONS]; }
delete[] quarterly_sales_form;
return 0;
}
/*############################################
# read_company_divisions_and_sales_quarters #
############################################*/
void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < QUARTERS; count++)
{
for (int index = 0; index < DIVISIONS; index++)
{
cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << " ";
getline(cin, temp);
stringstream(temp) >> array[count][index];
}
}
}
/*################################
# display_quarterly_sales_array #
#################################*/
void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < DIVISIONS; count++)
{
cout << "\nCompany division #" << count+1 << ":\n";
for (int index = 0; index < QUARTERS; index++)
{ cout << array[count][index] << ", "; }
}
}
Can some kind soul please tell me what I'm doing wrong?
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
In this line, COMPANY_DIVISIONS should be count.
In addition to what Dan Hulme said, it seems this line
stringstream(temp) >> array[count][index];
should really be
std::istringstream(temp) >> std::skipws >> array[index][count];
In addition to using std::istringstream rather than std::stringstream and making sure that an lvalue is at hand, which isn't strictly needed until the type read becomes more interesting, this also reverses the indices: index runs over COMPANY_DIVISIONS and count over SALES_QUARTERS.
The real question is, of course: Who hands out assignments like this? Pointer manipulations and allocations are best left to low-level library writers. This is C++ not C: we can and should use abstractions. Getting this code exception safe is a major challenge and there is no point in teaching people how to write broken (e.g. exception unsafe) code.