shankarraj
asked on
sending integer array of data
Hi,
I am generating some numbers in my server program. I would like to send this integer array to the client in the form of message.
I will retrieve the sent numbers using the header in client.
The generated numbers is in the form of integer array as:
int MyNumbers[10];
These numbers are put into message as:
char charArrData[100];
sprintf(charArrData, "<Message><MyNumbers><head er>NumberS eries</hea der><data>
%d</data></MyNumbers></Mes sage>", Numbers);
Here , I am facing the problem in forming the message using the inetger array by using sprintf().
Please help me like how to form the message using the sprintf( ) here and getting the value using the header at the client side.
Thanks,
shankarraj
I am generating some numbers in my server program. I would like to send this integer array to the client in the form of message.
I will retrieve the sent numbers using the header in client.
The generated numbers is in the form of integer array as:
int MyNumbers[10];
These numbers are put into message as:
char charArrData[100];
sprintf(charArrData, "<Message><MyNumbers><head
%d</data></MyNumbers></Mes
Here , I am facing the problem in forming the message using the inetger array by using sprintf().
Please help me like how to form the message using the sprintf( ) here and getting the value using the header at the client side.
Thanks,
shankarraj
ASKER
Hi,
Let us assume that I have sent following mesage from my server program and the message is received at my client program as:
<Message><MyNumbers><heade r>NumberSe ries</head er><data>2 0,41,57</d ata></MyNu mbers></Me ssage>
Also, I would like my API as:
HubMessage *ptrMessage;
int Numbers[3]=ptrHubMessage-> getFieldVa lue("Numbe rSeries", 1);
Please tell me like how to I retrieve the array of integers from the message in the above case as the array of numbers are separated by a comma in the mesage?
Thanks,
shankarraj
Let us assume that I have sent following mesage from my server program and the message is received at my client program as:
<Message><MyNumbers><heade
Also, I would like my API as:
HubMessage *ptrMessage;
int Numbers[3]=ptrHubMessage->
Please tell me like how to I retrieve the array of integers from the message in the above case as the array of numbers are separated by a comma in the mesage?
Thanks,
shankarraj
Do you need a pure C solution?
A C++ solution will be cleaner and easier.
A C++ solution will be cleaner and easier.
ASKER
Hi,
I am looking for C++ solution.
I would like to retrieve all the array values at a stretch from the message in the client side as I mentioned earlier. i.e. int Numbers[3]=ptrHubMessage-> getFieldVa lue("Numbe rSeries", 1);
Please help me to do this.
Thanks,
shankarraj
I am looking for C++ solution.
I would like to retrieve all the array values at a stretch from the message in the client side as I mentioned earlier. i.e. int Numbers[3]=ptrHubMessage->
Please help me to do this.
Thanks,
shankarraj
>> int Numbers[3]=ptrHubMessage-> getFieldVa lue("Numbe rSeries", 1);
How you will know that there are 3 elements before parsing the values?
A pure C solution will require a malloc() or calloc() allocation;
A C++ solution will require to create the array with a new operator.
so, it could be something like:
int *Numbers = ptrHubMessage->getFieldVal ue("Number Series", 1);
don't know what 1 means.
But Numbers will not tell you the array size. A more C++ like solution will be:
std::vector<int> *Numbers = ptrHubMessage->getFieldVal ue("Number Series", 1);
To acomplish this, you will have to parse the message itself, and extract the numbers array as a string. a STL std::string will be easier to process.
Then you have to split the string into values. Something like this:
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",", 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str. substr(las tPos, pos - lastPos).c_str()));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",", pos);
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
How you will know that there are 3 elements before parsing the values?
A pure C solution will require a malloc() or calloc() allocation;
A C++ solution will require to create the array with a new operator.
so, it could be something like:
int *Numbers = ptrHubMessage->getFieldVal
don't know what 1 means.
But Numbers will not tell you the array size. A more C++ like solution will be:
std::vector<int> *Numbers = ptrHubMessage->getFieldVal
To acomplish this, you will have to parse the message itself, and extract the numbers array as a string. a STL std::string will be easier to process.
Then you have to split the string into values. Something like this:
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",",
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str.
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",",
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
ASKER
Hi,
int Numbers[3]=ptrHubMessage-> getFieldVa lue("Numbe rSeries", 1);
where 1 is the row number.
Also, as you have told, I will not be knowing that there are 3 elements before parsing the values. There may be any number of elements in the array.
Thanks,
shankarraj
int Numbers[3]=ptrHubMessage->
where 1 is the row number.
Also, as you have told, I will not be knowing that there are 3 elements before parsing the values. There may be any number of elements in the array.
Thanks,
shankarraj
Being 1 the row number, you have to scan all the file until you reach the desired row.
but in an XML document, a row is an ambigous term, maybe a record, or Message number would be more exact, because a Message can occupy more than 1 text rows, or maybe 2 messages can occupy 1 single text rows.
Sounds like you will require some xml parser ...
but in an XML document, a row is an ambigous term, maybe a record, or Message number would be more exact, because a Message can occupy more than 1 text rows, or maybe 2 messages can occupy 1 single text rows.
Sounds like you will require some xml parser ...
>>>> int Numbers[3]=ptrHubMessage-> getFieldVa lue("Numbe rSeries", 1);
That cannot work for different reasons:
1. A fixed array variable like 'int Numbers[3]' only can be initialized by a const array:
int Numbers[3] = { 1, 2, 3};
but not by a function return value.
2. The function at the right side of an assignment doesn't know the size of the array to return. If it is dynamic we need a dynamic array at the left side of the assignment as well.
You can heal both by something like
int Numbers[3];
if (ptrHubMessage->getFieldVa lue(Number s, 3, "NumberSeries", 1))
{
// ok we got 3 values from serialized message
}
where the getFieldValue has overloads for different result types.
Regards, Alex
That cannot work for different reasons:
1. A fixed array variable like 'int Numbers[3]' only can be initialized by a const array:
int Numbers[3] = { 1, 2, 3};
but not by a function return value.
2. The function at the right side of an assignment doesn't know the size of the array to return. If it is dynamic we need a dynamic array at the left side of the assignment as well.
You can heal both by something like
int Numbers[3];
if (ptrHubMessage->getFieldVa
{
// ok we got 3 values from serialized message
}
where the getFieldValue has overloads for different result types.
Regards, Alex
ASKER
Hi jaime_olivares:,
Please tell me like how to read the integer array values from the vector: tokens in the following program which is given by you in your earlier answer:
std::vector<int> *Numbers = ptrHubMessage->getFieldVal ue("Number Series", 1);
To acomplish this, you will have to parse the message itself, and extract the numbers array as a string. a STL std::string will be easier to process.
Then you have to split the string into values. Something like this:
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",", 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str. substr(las tPos, pos - lastPos).c_str()));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",", pos);
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
Please help me here to read the integer array values from the vector tokens .
Thanks,
shankarraj
Please tell me like how to read the integer array values from the vector: tokens in the following program which is given by you in your earlier answer:
std::vector<int> *Numbers = ptrHubMessage->getFieldVal
To acomplish this, you will have to parse the message itself, and extract the numbers array as a string. a STL std::string will be easier to process.
Then you have to split the string into values. Something like this:
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",",
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str.
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",",
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
Please help me here to read the integer array values from the vector tokens .
Thanks,
shankarraj
vector<> is similar to an array. Easiest way to access is with direct indexing, like:
int a;
for (int i=0; i<theVector.size(); i++)
{
a= theVector[i];
// do something with a
}
int a;
for (int i=0; i<theVector.size(); i++)
{
a= theVector[i];
// do something with a
}
Also, assumming you will hold the vector object with a pointer, it shoul be:
int a;
for (int i=0; i<pVector->size(); i++)
{
a= (*pVector)[i];
// do something with a
}
finally you have to discard the vector object when you no longer need it, to avoid a memory leak:
delete pVector;
int a;
for (int i=0; i<pVector->size(); i++)
{
a= (*pVector)[i];
// do something with a
}
finally you have to discard the vector object when you no longer need it, to avoid a memory leak:
delete pVector;
ASKER
Hi jaime_olivares,
<Message><MyNumbers><heade r>NumberSe ries</head er><data>9 ,5,26,30,4 3,39,31,30 ,40,10,32< /data></My Numbers></ Message>
For the above message, when I used following vector program:
I am getting the output value as: 0 5 26 30 43 39 31 30 40 10 32
Note: I am using cout<<atoi(str.substr(last Pos, pos - lastPos).c_str()); in your program to display the values.
I am observing value: 0 instead of 9. Please tell me the problem for receiving value 0 instead of 9 here.
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",", 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str. substr(las tPos, pos - lastPos).c_str()));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",", pos);
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
<Message><MyNumbers><heade
For the above message, when I used following vector program:
I am getting the output value as: 0 5 26 30 43 39 31 30 40 10 32
Note: I am using cout<<atoi(str.substr(last
I am observing value: 0 instead of 9. Please tell me the problem for receiving value 0 instead of 9 here.
vector<int>* ParseValues(const string& str)
{
vector<int>* tokens = new vector<int>();
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(",",
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(",", lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(atoi(str.
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(",",
// Find next "non-delimiter"
pos = str.find_first_of(",", lastPos);
}
}
you cannot pass all the string to the ParseValues function, you have to separate first to have just:
9,5,26,30,43,39,31,30,40,1 0,32
9,5,26,30,43,39,31,30,40,1
ASKER
Hi jaime olivares,
I need to retrieve all the values from the message:
<Message><MyNumbers><heade r>NumberSe ries</head er><data>9 ,5,26,30,4 3,39,31,30 ,40,10,32< /data></My Numbers></ Message>
Please help me to do this using your vector program.
Thanks,
shankarraj
I need to retrieve all the values from the message:
<Message><MyNumbers><heade
Please help me to do this using your vector program.
Thanks,
shankarraj
could be something like this:
std::string full = "<Message><MyNumbers><head er>NumberS eries</hea der><data> 9,5,26,30, 43,39,31,3 0,40,10,32 </data></M yNumbers>< /Message>"
int start = full.find("<data>",0);
int end = full.find("</data",0);
if (start!=std::string::npos && end!=std::string::npos)
{
std:string portion = full.substr(start+6, start-end-6);
vector<int> *list = ParseValues(portion);
}
std::string full = "<Message><MyNumbers><head
int start = full.find("<data>",0);
int end = full.find("</data",0);
if (start!=std::string::npos && end!=std::string::npos)
{
std:string portion = full.substr(start+6, start-end-6);
vector<int> *list = ParseValues(portion);
}
Better use:
int ParseValues(const string& s, vector<int>& tokens)
{
string str = s; // take a writeable copy
s += ','; // add a delimiter at end
string::size_type lastPos = 0;
string::size_type pos = 0;
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
lastPos = pos+1;
}
}
return tokens.size();
}
Regards, Alex
int ParseValues(const string& s, vector<int>& tokens)
{
string str = s; // take a writeable copy
s += ','; // add a delimiter at end
string::size_type lastPos = 0;
string::size_type pos = 0;
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
lastPos = pos+1;
}
}
return tokens.size();
}
Regards, Alex
correction:
int ParseValues(const string& s, vector<int>& tokens)
{
string str = s; // take a writeable copy
s += ','; // add a delimiter at end
string::size_type lastPos = 0;
string::size_type pos = 0;
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
}
lastPos = pos+1; // must be done in every case
}
return tokens.size();
}
int ParseValues(const string& s, vector<int>& tokens)
{
string str = s; // take a writeable copy
s += ','; // add a delimiter at end
string::size_type lastPos = 0;
string::size_type pos = 0;
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
}
lastPos = pos+1; // must be done in every case
}
return tokens.size();
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>>>> the problem is that the author is sending the full xml string to the Parse function
The above parser should work beside of the very first number cause it only extracts numbers separated by comma. To make it valid when passing all xml string it is:
int ParseValues(const string& s, vector<int>& tokens)
{
string::size_type pos = s.find("<data>");
string::size_type lastPos = s.find("</data>");
if (pos == string::npos || lastPos == string::npos || lastPos < pos)
return -1; // invalid xml
pos += sizeof("<data>")-1;
string str = s.substr(pos, lastPos - pos); // take data portion
str += ','; // add a delimiter at end
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
}
lastPos = pos+1; // must be done in every case
}
return tokens.size();
}
That should do it.
The above parser should work beside of the very first number cause it only extracts numbers separated by comma. To make it valid when passing all xml string it is:
int ParseValues(const string& s, vector<int>& tokens)
{
string::size_type pos = s.find("<data>");
string::size_type lastPos = s.find("</data>");
if (pos == string::npos || lastPos == string::npos || lastPos < pos)
return -1; // invalid xml
pos += sizeof("<data>")-1;
string str = s.substr(pos, lastPos - pos); // take data portion
str += ','; // add a delimiter at end
while ((pos = str.find(',', lastPos)) != string::npos)
{
// Found a token, add it to the vector.
if (pos > lastPos)
{
int i;
istringstream iss(str.substr(lastPos, pos - lastPos));
if (iss >> i)
{
tokens.push_back(i);
}
}
lastPos = pos+1; // must be done in every case
}
return tokens.size();
}
That should do it.
Correction:
lastPos = 0; // reset lastPos before while loop
lastPos = 0; // reset lastPos before while loop
my ParseValues proposal is just to parse a clean list, not the entire XML, I think mixing both tasks does not contribute to legibility.
That's why I have put in a separted post.
That's why I have put in a separted post.
>>>> I think mixing both tasks does not contribute to legibility.
You are right. But if the xml is only 'boxing' and is not intended to provide a full independent and enhanceable xml document, parsing it that way maybe is a pragmatical approach. I am pretty sure that there are much more self-written parsers like the one I posted than full xml parsers. But the asker has to decide.
You are right. But if the xml is only 'boxing' and is not intended to provide a full independent and enhanceable xml document, parsing it that way maybe is a pragmatical approach. I am pretty sure that there are much more self-written parsers like the one I posted than full xml parsers. But the asker has to decide.
char OneNumber[10]; /* add this */
int MyNumbers[10];
char charArrData[100]; /* I suggest you to use 200 */
int i;
strcpy(charArrData, "<Message><MyNumbers><head
for (i=0; i<10; i++)
{
sprintf(OneNumber, "%s%d", i>0?",":"", MyNumbers[i]); /* add a comma, excepting 1st value */
strcat(charArrData, OneNumber);
}
strcat(charArrData, "</data></MyNumbers></Mess