C++ help

Journer

Banned
Jun 30, 2005
4,355
0
0
so i've got an array of integers that i need to store around 14k values in. however if i try to make the array larger than around 7500 (i.e int x[7500] then the program crashes.

any ideas on what i could do?
 

Journer

Banned
Jun 30, 2005
4,355
0
0
yah i thought about a matrix...

i think i figured it out

if i use

short x[];

i can go up to around 17k vars...hopefully this will work >.>

atm i have

short mkr[17000];

the variables are never more than the integer 31536000
most are under 100
a few are over 100 but under 604800

i'de post the code but i'm not done so it wont make any sense, heh
 

Journer

Banned
Jun 30, 2005
4,355
0
0
hmm well now program is acting up and returning negative numbers because they are too long to be ints or shorts (i think)

argh >_<!
 

Journer

Banned
Jun 30, 2005
4,355
0
0
well...here is what i am working on:
we are supposed to read in information from a file that looks like this:
4:45 imapd
3:14 imapd
4:26 imapd
06:35:10 imapd
02:25:22 imapd
04:22:59 imapd
1:09 imapd
0:35 imapd
3:16 imapd
8:53 imapd
22:58:17 imapd
9:16 imapd

when i read it into an array (or string) it looks like:

4:45imapd3:14imapd4:26imapd06:35:10imapd

so this is where i am now. this format is like:
days-hours:minutes:seconds impad

i am supposed to extract all the numbers and get the average time a user is spending running the imap daemon. how i am doing this is extracting the numbers from an array and putting them into an int:
switch(array[x])
case '1': i[x]=1;

and so on.
i use the '-', ':', and 'i' to multiply everything into seconds.
ex: there are 86400 seconds in a day. so when the program finds '-' it multiplys the number behind it by 86400. the : multiple everything by 60. if it finds two that are 3 characters apart it multiplies twice (to convert hours to minutes to seconds).

so...here is what i've got so far:


#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int doConvert(int,char [],string);

int main(){
string input,str;
char c[1000000];
int x=0,y=0;
ifstream read("dataFile");
if (read.is_open()){
while(! read.eof()){
read>>c[x];
input=input+c[x];
x++;
y++;}
read.close();
}
else cout<<"Unable to open dataFile.";
x=0;
int size = input.size();
doConvert(size,c,input);
return 0;}

int doConvert(int s,char carray[],string inp){
int x=0;
short mkr[17000];
cout<<inp<<endl;
cout<<s<<endl;
while(s>0){
if(carray[x]=='-'){
mkr[x-1]=mkr[x-1]*86400;
//cout<<"a - found; mkr now= "<<mkr[x-1]<<endl;
}
else if(carray[x]==':'){
if((carray[x-2]!='1')||(carray[x-2]!='2')||(carray[x-2]!='3')||(carray[x-2]!='4')||(carray[x-2]!='5')||(carray[x-2]!='6')||(carray[x-2]!='7')||(carray[x-2]!='8')||(carray[x-2]!='9')||(carray[x-2]!='0')){
mkr[x-1]=mkr[x-1]*60;}
else{
int t1,t2;
t1=mkr[x-2]*10;
t2=mkr[x-1];
mkr[x-2]=(t1+t2)*60;
mkr[x-1]=0;
if (carray[x+3]==':'){mkr[x-2]=mkr[x-2]*60;}
else {x=x;}}
}
else if(carray[x]=='i'){
int t3,t4;
t3=mkr[x-2]*10;
t4=mkr[x-1];
mkr[x-2]=t3+t4;
mkr[x-1]=0;
}
else{
switch (carray[x]){
case '1': mkr[x]=1;
break;
case '2': mkr[x]=2;
break;
case '3': mkr[x]=3;
break;
case '4': mkr[x]=4;
break;
case '5': mkr[x]=5;
break;
case '6': mkr[x]=6;
break;
case '7': mkr[x]=7;
break;
case '8': mkr[x]=8;
break;
case '9': mkr[x]=9;
break;
case '0': mkr[x]=0;
break;
default: x=x;
}}
x++;
s--;}
int total=0;
while(x>0){total=total+mkr[x];
x--;}
cout<<mkr[31]<<" "<<mkr[4353]<<" "<<mkr[9999]<<" "<<mkr[12000]<<endl;

cout<<endl<<"Total is: "<<total<<" seconds."<<endl;



return 0;}


 

aCynic2

Senior member
Apr 28, 2007
710
0
0
Originally posted by: Journer
hmm well now program is acting up and returning negative numbers because they are too long to be ints or shorts (i think)

argh >_<!

Are you using unsigned ints?

Man, Anandtech really needs to work on their forum software. It's going to be hard as hell to read your code posting.

Ok, I see something:

short mkr[17000];

I believe a short is still a two byte integer, thus it's 0-65536 or -32767 to 32768 for signed numbers.

Make the declaration an unsigned int.

ADDENDUM: from msdn2, a short is: 0 to 65,535 unsigned and ?32,768 to 32,767 signed.

 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
Why on earth are you doing this in C++?

I would HIGHLY suggest using Perl for this.
 

aCynic2

Senior member
Apr 28, 2007
710
0
0
Originally posted by: Crusty
Why on earth are you doing this in C++?

I would HIGHLY suggest using Perl for this.

Something this basic could also be done in awk, tcl/tk or any number of other languages.
 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
Originally posted by: aCynic2
Originally posted by: Journer
hmm well now program is acting up and returning negative numbers because they are too long to be ints or shorts (i think)

argh >_<!

Are you using unsigned ints?

Man, Anandtech really needs to work on their forum software. It's going to be hard as hell to read your code posting.

Ok, I see something:

short mkr[17000];

I believe a short is still a two byte integer, thus it's 0-65536 or -32767 to 32768 for signed numbers.

Make the declaration an unsigned int.

ADDENDUM: from msdn2, a short is: 0 to 65,535 unsigned and ?32,768 to 32,767 signed.

Shorts are required to be at least 16-bit, but might be more. It all depends on the OS/Compiler used.

 

Journer

Banned
Jun 30, 2005
4,355
0
0
Originally posted by: aCynic2
Originally posted by: Journer
hmm well now program is acting up and returning negative numbers because they are too long to be ints or shorts (i think)

argh >_<!

Are you using unsigned ints?

Man, Anandtech really needs to work on their forum software. It's going to be hard as hell to read your code posting.

Ok, I see something:

short mkr[17000];

I believe a short is still a two byte integer, thus it's 0-65536 or -32767 to 32768 for signed numbers.

Make the declaration an unsigned int.

ADDENDUM: from msdn2, a short is: 0 to 65,535 unsigned and ?32,768 to 32,767 signed.

i dont know the difference between signed and unsigned ints

how could i store some intergers in an array where the array has to be at least 14k (storage spots) long and each individual storage spot needs to be able to go up to the number 1,000,000. i need no negatives or decimals.

crusty: this is for a c++ class, i dont have a choice
acynic2: again, no choice
crusty: i tried compiling it in linux. still doesnt work right
 

smack Down

Diamond Member
Sep 10, 2005
4,507
0
0
You need to allocate the memory on the heap. You are blowing up the stack. Use malloc.

int* bigArray = malloc(sizeOfArray * sizeof(int));

Edit a signed int is the default the last bit is used to store the sign of the number. An unsigned integer uses all bits to store the value.
 

aCynic2

Senior member
Apr 28, 2007
710
0
0
Originally posted by: smack Down
You need to allocate the memory on the heap. You are blowing up the stack. Use malloc.

int* bigArray = malloc(sizeOfArray * sizeof(int));

Edit a signed int is the default the last bit is used to store the sign of the number. An unsigned integer uses all bits to store the value.

Forgot about this. I remember back in the DOS days, the stack was a mere 2K. Even if they increased it, you're allocating 17000 * sizeof (short) which could be 34000 or 68000.

You probably are overflowing the stack.
 

Journer

Banned
Jun 30, 2005
4,355
0
0
well i monkied around with it and i got it to work under linux
fortunately this is a unix c++ class so this should be acceptable...
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Originally posted by: smack Down
You need to allocate the memory on the heap. You are blowing up the stack. Use malloc.

int* bigArray = malloc(sizeOfArray * sizeof(int));

Edit a signed int is the default the last bit is used to store the sign of the number. An unsigned integer uses all bits to store the value.

or a static int[xxxxx]


BTW why are you u reading all of these numbers into an array? Since you are calculating the average you don't need to store every single value. All you need to do is keep track of the sum and number of records. Your result is (double)sum/(double)n.

If you need sdev and stuff, there are equations that do not need to know the average before hand... so that you don't have to store every single value.


Also, looking at your code you seem to be doing some crazy stuff reading your data in.
if (read.is_open()){
while(! read.eof()){
read>>c[x];
input=input+c[x];
x++;
y++;}
read.close();
}

You are basically reading the whole file into a c++ string a character at a time... this is pretty inefficient and makes parsing the text tough.

Since each record is on a seperate line you should read the data in one line at a time.

Look at:
http://www.cplusplus.com/refer...m/istream/getline.html

This will get only something like: 4:45 imapd.

Also... you don't have to do the crazy string->int conversions yourself
http://www.cplusplus.com/refer...rary/cstdlib/atoi.html


 

singh

Golden Member
Jul 5, 2001
1,449
0
0
If you need a simple array in C++, please use the standard vector class instead:

#include <vector>
...
std::vector<int> numVec;
numVec.resize(maxNumItems);
...
numVec[0] = ...
 

Journer

Banned
Jun 30, 2005
4,355
0
0
statik: ill try using the static int[xx]
also, i read it into an array so i could use the values '-', ':', 2 instances of ':' within three characters of each other (in the array), and 'i' to multiple the minutes, seconds, hours, days and take care of the tenths spots. i dont know of any way to extract the values from a string and do that.

please understand that this project is for a very basic programming course and i suck ass at programming. the program is not supposed to be efficient, it is just supposed to work, however i can get it to do so. if it hogs up a shit load of memory, it doesn't matter (unless it is leaking).

also, if you look at the code deeper, the ONLY reason i read it into a string is so i could easily get the amount of characters that are in the array with str.size(); i dont know how to get the size of the array without doing that.

i didnt use getline because it would make things more difficult to parse through. i would have to deal with spaces, tabs, etc. and i dont know how to extract values from strings. using this char array may be a bit basic, but logically it seems to be working.

i looked at the string-> int conversion page and i did not understand how it could help. sorry for being such a newb >_<

singh: i should have thought about this earlier. i will probably try to change it into a vector now. that seems like a much better idea.
 

Journer

Banned
Jun 30, 2005
4,355
0
0
singh: well i converted it to a vector. it now works fine in DOS and linux, w00t...now i am working on fixing a little math problem i cant seem to work out...having to do with the multiplication of variables between two semicolons.
 

aCynic2

Senior member
Apr 28, 2007
710
0
0
Originally posted by: Journer
singh: well i converted it to a vector. it now works fine in DOS and linux, w00t...now i am working on fixing a little math problem i cant seem to work out...having to do with the multiplication of variables between two semicolons.

Do you have a variable limiter in a for loop?
 

Journer

Banned
Jun 30, 2005
4,355
0
0
Originally posted by: aCynic2
Originally posted by: Journer
singh: well i converted it to a vector. it now works fine in DOS and linux, w00t...now i am working on fixing a little math problem i cant seem to work out...having to do with the multiplication of variables between two semicolons.

Do you have a variable limiter in a for loop?

if i understand your vocab correctly, yes.

the problem has got something to do with a logic error when the program finds a semicolon then another semicolon three chars later...i'm still trying to figure it out...

this code should work with just about any compiler:

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;

int doConvert(int,char [],string);

int main(){
string input,str;
char c[1000000];
int x=0,y=0;
ifstream read("dataFile");
if (read.is_open()){
while(! read.eof()){
read>>c[x];
input=input+c[x];
x++;
y++;}
read.close();
}
else cout<<"Unable to open dataFile.";
x=0;
int size = input.size();
doConvert(size,c,input);
return 0;}

int doConvert(int s,char carray[],string inp){
int x=0,dummy=0;
std::vector<int> mkr;
mkr.resize(s+1);
int t1=0,t2=0,t3=0,t4=0;
while(s>0){
switch (carray[x]){
case '-':
mkr[x-1]=mkr[x-1]*86400;
break;
case ':':
cout<<"x-2 is: "<<carray[x-2]<<endl;
if((carray[x-2]!='1')||(carray[x-2]!='2')||(carray[x-2]!='3')||(carray[x-2]!='4')||(carray[x-2]!='5')||(carray[x-2]!='6')||(carray[x-2]!='7')||(carray[x-2]!='8')||(carray[x-2]!='9')){
mkr[x-1]=mkr[x-1]*60;
mkr[x]=0;
if (carray[x+3]==':'){mkr[x-1]=mkr[x-1]*60;}
else {x=x;}}
/////////
else{
t1=mkr[x-2]*10;
t2=mkr[x-1];
t3=t1+t2;
mkr[x-2]=t3*60;
mkr[x-1]=0;
mkr[x]=0;
t1=0;
t2=0;
t3=0;
if (carray[x+3]==':'){mkr[x-2]=mkr[x-2]*60;}
else {dummy=dummy;}}
///////////
break;
case 'i':
t3=mkr[x-2]*10;
t4=mkr[x-1];
mkr[x-2]=t3+t4;
mkr[x-1]=0;
mkr[x]=0;
t3=0;
t4=0;
break;
case '1': mkr[x]=1;
break;
case '2': mkr[x]=2;
break;
case '3': mkr[x]=3;
break;
case '4': mkr[x]=4;
break;
case '5': mkr[x]=5;
break;
case '6': mkr[x]=6;
break;
case '7': mkr[x]=7;
break;
case '8': mkr[x]=8;
break;
case '9': mkr[x]=9;
break;
case '0': mkr[x]=0;
break;
default: mkr[x]=0;
}
x++;
s--;}
int total=0,count=0;
double ans;
while(x>=0){
cout<<"marker at '"<<x<<"' is: "<<mkr[x]<<endl;
if (mkr[x]==0){x--;}
else {total=total+mkr[x];
count++;
x--;}}
cout<<endl<<"Total is: "<<total<<" seconds."<<endl;
ans=total/count;
cout<<endl<<"The average time spend on imapd is: "<<ans<<" seconds."<<endl;




return 0;}

place a file called dataFile in the same directory that contains the following to get the same output i am:

4:45 imapd
3:14 imapd
4:26 imapd
06:35:10 imapd
02:25:22 imapd
04:22:59 imapd
1:09 imapd
1-03:01:22 imapd

you will notice that the 35 in 06:35:10 is being computed as: 3 and 300 (300 because 60x5 is 300) it is supposed to add them together and be 2100 (35x60). having the same problem for the other ones :/
 

aCynic2

Senior member
Apr 28, 2007
710
0
0
Originally posted by: Journer
Originally posted by: aCynic2
Originally posted by: Journer
singh: well i converted it to a vector. it now works fine in DOS and linux, w00t...now i am working on fixing a little math problem i cant seem to work out...having to do with the multiplication of variables between two semicolons.

Do you have a variable limiter in a for loop?

if i understand your vocab correctly, yes.

I never finished CompSci course work, so I didn't study the vocab...for me, I think of it

for ( initializer; limiter; increment)
{

}

I'd say more, but I'm at work and I can't take the time to really analyze your code.
 

KCfromNC

Senior member
Mar 17, 2007
208
0
76
OK, looking at the problem you're doing way too much work. I've attached a working example. I'd encourage you to use this as a basis for your own program and not just turn this in as is. I can't stop you, but if you're struggling now you need to put the work in to figure out why or things will get a lot worse for the next assignment.

First problem is that you're trying to process the whole file in one array. This is a bad idea for 2 reasons. First off, as you've found it's not straightforward to get an array large enough to hold the data. Second, even with your fix it's possible to overflow that array with a big enough file. So I've redone the program to read and parse a single line at a time. This cuts the memory requirement way down and eliminates the problem of having to guess how big the file is.

Each call to the doConvert function returns the number of seconds for that particular line. As mentioned previously in the responses, keeping a running total plus the number of lines processed allows you to calculate the average with only two variables instead of a possibly limitless array.

Next, I've used getline to read the line. This preserves the formatting of the data (spaces in this case) to make it easier to process. An there's no need to keep multiple copies of the data.

The processing function was also way too complex. For each line you have at most four integer values that need to be stored (seconds, minutes, hours, and days). To keep with your way of doing things, I've used a 4 entry array to hold this data.

I'm also working backwards through the time string. This has the advantage that you know that the first characters you read (the ones at the end of the time) are always the seconds. The next ones are always the minutes, and then the hours, and then the days.

I've used another variable to keep track of the value of the digit you're currently reading (multiplier). This is going to be 1, 10, 100, and so on. Your example data only uses 1 and 10, but 100 might be needed if the days count gets long enough. This multiplier is reset each time a : or - is seen because the next digit processed will be in the 1's place for that particular part of the time.

A final calculation combines the seconds, minutes, hours and days into one total count of seconds, and this is returned to the main function to add to the running total.

I haven't tested this with all of the example input you gave, so at the very least you'll want to do that to make sure I haven't missed anything. And be sure you understand what this is doing if you decide to use it for your program since the class isn't going to get any easier from here.

Oh, also get familiar with the idiom int x = c - '0'. I'll leave it as homework for you to figure out what that means. Same with if ((ch >= '0') && (ch <= '9')), and see where I use a library function to accomplish the same test.

also, if you look at the code deeper, the ONLY reason i read it into a string is so i could easily get the amount of characters that are in the array with str.size(); i dont know how to get the size of the array without doing that. Look at strlen().

#include <iostream>
#include <fstream>
using namespace std;

// Take a line of input data, return the number of seconds used
// for that particular line. Return 0 on parsing error (no data,
// missing imapd token, etc).
unsigned int doConvert(const char *inp_ptr)
{
const char *ptr = inp_ptr;
unsigned int time[4] = {0,0,0,0};
int time_idx = 3;
int multiplier = 1;

// Find space separating time from "imapd" string
while(*ptr && !isspace(*ptr))
ptr += 1;

// Return 0 if there is no space on the line or imapd doesn't come
// right after the space. This also throws out empty lines
if (!*ptr || strncmp(ptr + 1, "imapd", 5))
return 0;

// Work backwards through the time string. Fill in the time[] array
// starting from entry 3 (seconds) and work up to entry 0 (days). Not all
// time strings have the larger time values, but fill them in if they do exist.
for (ptr -= 1; ptr >= inp_ptr; ptr -= 1)
{
// Add this digit to the current time[] array entry, using multiplier
// to adjust it to the correct power of 10 for the digits position in the
// number
// Update that multiplier to keep track of the place of the next
// most significant digit read (ones, tens, hundreds and so on as needed)
if (isdigit(*ptr))
{
time[time_idx] += (*ptr - '0') * multiplier;
multiplier *= 10;
}
// Hitting : or - means that the next entry in the time[] array
// needs to be used
// Reset multiplier to 1 since the first char is always in the ones place
else if ((*ptr == ':') || (*ptr == '-'))
{
time_idx -= 1;
multiplier = 1;
}
}

// convert individual parts of the time string (days, hours, minutes, seconds)
// into one value holding just the number of seconds.
// time[0] = days
// time[1] = hours
// time[2] = minutes
// time[3] = seconds
return (((time[0] * 24) + time[1]) * 60 + time[2]) * 60 + time[3];
}

int main()
{
char c[256];

unsigned int rc;
unsigned int lines = 0;
double total = 0.0;

ifstream read("dataFile");
if (read.is_open())
{
while(! read.eof())
{
// use getline here to preserve white space and other formatting
read.getline(c, sizeof(c));
rc = doConvert(c);
// The function returns 0 if there's no data on the current line
// If convert_line returns anything other than 0, the value is
// the number of seconds extracted from the time string on the
// current line.
if (rc)
{
total += rc;
lines += 1;
}
}
read.close();
cout << endl << "Total is: " << total << " seconds." << endl;
cout << endl << "The average time spend on imapd is: " << total/lines << " seconds." << endl;
}
else
cout << "Unable to open dataFile.";
return 0;
}
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |