Hi everyone!
I have a problem when working with string in text file.
For example, I have a text:
<w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="1799590" cy="1799590"/><wp:extent cx="5486400" cy="3200400"/>
I 'd like to read from the beginning to the end of text file and get values of cx and cy.
What should I do to do that task?
Thanks for your help!
Ideally you'd prob want to use an XML parser library, then iterate over each Node with name "wp:extent" , then extract values of the attributes "cx" , "cy"
I'm not very experienced with XML files so I copied this text to .txt file.
That's silly. Not only do lots of editors have XML syntax support, so that looking at it, the data seems organized and readable, but there are many perfectly good XML parsers out there, too, in almost any programming language. They'll extract any data you want in an instant.
#include <fstream>
#include <iostream>
usingnamespace std;
int linecount=1;
string line;
int main (int argc, char *argv[])
{
if (argc!=2)
{
cout << "Incorrect arguments\n";
}
else
{
ifstream inputfile (argv[1]);
if (inputfile.is_open())
{
cout << "CX" << "\tCY" << endl;
while ( inputfile.good())
{
getline (inputfile,line);
if (!line.empty())
{
for (int i =0; i <= line.size(); i++)
{
if ((line[i] == 'c') && (line[i+1] == 'x') && (line[i+2] == '='))
{
// cout << "CX= found at " << i << endl;
cout << line [i+4]<< line [i+5]<< line [i+6]<< line [i+7]<< line [i+8]<< line [i+9]<< line [i+10];
}
if ((line[i] == 'c') && (line[i+1] == 'y') && (line[i+2] == '='))
{
// cout << "CY= found at " << i << endl;
cout << "\t" << line [i+4]<< line [i+5]<< line [i+6]<< line [i+7]<< line [i+8]<< line [i+9]<< line [i+10] << endl;
}
}
}
}
inputfile.close();
}
else
{
cout << "File not open" << endl;;
}
}
return 0;
}
There are many powerful tools to search for a specific patterns with regular expressions. You can use 'awk' for example which let you do the task you are asking for and even much more. You can learn more about it here https://www.gnu.org/software/gawk/
Then just modify the code to get all digits between the quotes.
If the numbers you want are all in the same column space that would be another way to just grab a certain range. Since I don't have your data file I can't say.
slepeckypes, don't be afraid of trying libraries. Trust me, step 1 is choosing an XML library. A lot of them are lightweight, too. For example, https://github.com/zeux/pugixml
You'll look back on this and be like, "oh, all i needed to do was include this one header file, compile my lib against that one, and write <10 lines ...?"
I agree with icy1. A xml library is the easiest way to go. pugixml is easy to use and well documented.
However it would require a complete well-formed and valid xml document.
With the snippet you showed every xml lib will fail.
If you have only a snippet then it would be better to follow SamuelAdams way.
I agree with everyone above. There are much better and faster ways but given a one line example. I hacked it. First idea I came up with worked so.... I left it there.
#include <iostream>
#include <fstream>
#include <string>
usingnamespace std;
void pause();
int main()
{
fstream file;
char foundCharacter;
int position;
string temporalString = "",
fileString,
cx1,
cy1,
cx2,
cy2;
file.open("readFromFile.txt");
if (file.fail())
exit(1);
else
cout << "\nFile successfully opened!";
getline(file, fileString); //read string from file
//CX1
position = fileString.find("cx=\"", 0 ); //find first position of first "cx=" in string
position += 4; //increment position to skip " sign;
for (position; foundCharacter != '\"' ; position ++) //read every character that's a number untill " is found
{
foundCharacter = fileString.at(position);
if (foundCharacter != '\"')
temporalString.push_back(foundCharacter);
elsebreak;
}
cx1 = temporalString; //set first cx result
//CX2
position = fileString.find("cx=\"", position ); //find next position of "cx=" in string
temporalString.clear(); //clear temporalString
foundCharacter = '\0'; //clear character
position += 4; //increment position to skip " sign;
for (position; foundCharacter != '\"' ; position ++) //read every character that's a number untill " is found
{
foundCharacter = fileString.at(position);
if (foundCharacter != '\"')
temporalString.push_back(foundCharacter);
elsebreak;
}
cx2 = temporalString;
//CY1
position = fileString.find("cy=\"", 0 ); //find next position of first "cy=" in string
temporalString.clear(); //clear temporalString
foundCharacter = '\0'; //clear character
position += 4; //increment position to skip " sign;
for (position; foundCharacter != '\"' ; position ++) //read every character that's a number untill " is found
{
foundCharacter = fileString.at(position);
if (foundCharacter != '\"')
temporalString.push_back(foundCharacter);
elsebreak;
}
cy1 = temporalString;
//CY2
position = fileString.find("cy=\"", position ); //find next position of "cy=" in string
temporalString.clear(); //clear temporalString
foundCharacter = '\0'; //clear character
position += 4; //increment position to skip " sign;
for (position; foundCharacter != '\"' ; position ++) //read every character that's a number untill " is found
{
foundCharacter = fileString.at(position);
if (foundCharacter != '\"')
temporalString.push_back(foundCharacter);
elsebreak;
}
cy2 = temporalString;
cout << "\n\ncx1 = " << cx1
<< "\ncy1 = " << cy1
<< "\ncx2 = " << cx2
<< "\ncy2 = " << cy2;
pause();
return(0);
}
void pause()
{
std::cout << "\n\n\n Press enter to continue...";
std::cin.sync();
std::cin.get();
std::cout << "\n\n";
return;
}