C++ - Getting string of text inbetween character and text - c++
I'm making a console program that will get a line of text that starts with a specific character. I'm working with an .txt file as the input of text, and this is it:
<?xml version="1.0" encoding="utf-8"?>
<vector android:height="64.0dip" android:width="64.0dip" android:viewportWidth="24.0" android:viewportHeight="24.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00000000" android:pathData="M12.05,7.7c-1.1,0,-2,0.94,-2,2.05v0.5h4v-0.5C14.05,8.65,13.15,7.7,12.05,7.7z" />
<path android:fillColor="#*common:color/qs_toggles_color" android:pathData="M15.05,10.25l0.0,-0.5c0.0,-1.66 -1.34,-3.0 -3.0,-3.0s-2.99,1.34 -2.99,3.0l-0.01,0.5c-0.55,0.0 -1.0,0.45 -1.0,1.0l0.0,5.0c0.0,0.55 0.45,1.0 1.0,1.0l6.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0l0.0,-5.0C16.05,10.7 15.6,10.25 15.05,10.25zM12.05,14.75c-0.55,0.0 -1.0,-0.45 -1.0,-1.0c0.0,-0.55 0.45,-1.0 1.0,-1.0s1.0,0.45 1.0,1.0C13.05,14.3 12.6,14.75 12.05,14.75zM14.05,10.25l-4.0,0.0l0.0,-0.5c0.0,-1.1 0.9,-2.05 2.0,-2.05s2.0,0.94 2.0,2.05L14.05,10.25z" />
<path android:fillColor="#*common:color/qs_toggles_color" android:pathData="M16.5,2.5c3.3,1.5 5.6,4.7 6.0,8.5L24.0,11.0C23.4,4.8 18.3,0.0 12.0,0.0c-0.2,0.0 -0.4,0.0 -0.7,0.0l3.8,3.8L16.5,2.5zM7.5,21.5c-3.3,-1.5 -5.6,-4.7 -6.0,-8.5L0.1,13.0C0.6,19.2 5.7,24.0 12.0,24.0c0.2,0.0 0.4,0.0 0.7,0.0l-3.8,-3.8L7.5,21.5z" />
</vector>
What I want to do is extract
M12.05,7.7c-1.1,0,-2,0.94,-2,2.05v0.5h4v-0.5C14.05,8.65,13.15,7.7,12.05,7.7z
and:
M15.05,10.25l0.0,-0.5c0.0,-1.66 -1.34,-3.0 -3.0,-3.0s-2.99,1.34 -2.99,3.0l-0.01,0.5c-0.55,0.0 -1.0,0.45 -1.0,1.0l0.0,5.0c0.0,0.55 0.45,1.0 1.0,1.0l6.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0l0.0,-5.0C16.05,10.7 15.6,10.25 15.05,10.25zM12.05,14.75c-0.55,0.0 -1.0,-0.45 -1.0,-1.0c0.0,-0.55 0.45,-1.0 1.0,-1.0s1.0,0.45 1.0,1.0C13.05,14.3 12.6,14.75 12.05,14.75zM14.05,10.25l-4.0,0.0l0.0,-0.5c0.0,-1.1 0.9,-2.05 2.0,-2.05s2.0,0.94 2.0,2.05L14.05,10.25z
and:
M16.5,2.5c3.3,1.5 5.6,4.7 6.0,8.5L24.0,11.0C23.4,4.8 18.3,0.0 12.0,0.0c-0.2,0.0 -0.4,0.0 -0.7,0.0l3.8,3.8L16.5,2.5zM7.5,21.5c-3.3,-1.5 -5.6,-4.7 -6.0,-8.5L0.1,13.0C0.6,19.2 5.7,24.0 12.0,24.0c0.2,0.0 0.4,0.0 0.7,0.0l-3.8,-3.8L7.5,21.5z
and put them into their own strings. I have tried to do this by deleting all of the text before those strings and after, but I get an Unhandled exception, with this code:
int main(int argc, const char * argv[])
{
string str = "<?xml versim on=\"1.0\" encoding=\"utf-8\"?> <vector android:height=\"64.0dip\" android:width=\"64.0dip\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\" xmlns:android=\"http://schemas.android.com/apk/res/android\"> <path android:fillColor=\"#00000000\" android:pathData=\"M12.05,7.7c-1.1,0,-2,0.94,-2,2.05v0.5h4v-0.5C14.05,8.65,13.15,7.7,12.05,7.7z\" /> <path android:fillColor=\"#*common:color/qs_toggles_color\" android:pathData=\"M15.05,10.25l0.0,-0.5c0.0,-1.66 -1.34,-3.0 -3.0,-3.0s-2.99,1.34 -2.99,3.0l-0.01,0.5c-0.55,0.0 -1.0,0.45 -1.0,1.0l0.0,5.0c0.0,0.55 0.45,1.0 1.0,1.0l6.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0l0.0,-5.0C16.05,10.7 15.6,10.25 15.05,10.25zM12.05,14.75c-0.55,0.0 -1.0,-0.45 -1.0,-1.0c0.0,-0.55 0.45,-1.0 1.0,-1.0s1.0,0.45 1.0,1.0C13.05,14.3 12.6,14.75 12.05,14.75zM14.05,10.25l-4.0,0.0l0.0,-0.5c0.0,-1.1 0.9,-2.05 2.0,-2.05s2.0,0.94 2.0,2.05L14.05,10.25z\" <path android:fillColor=\"#*common:color/qs_toggles_color\" android:pathData=\"M16.5,2.5c3.3,1.5 5.6,4.7 6.0,8.5L24.0,11.0C23.4,4.8 18.3,0.0 12.0,0.0c-0.2,0.0 -0.4,0.0 -0.7,0.0l3.8,3.8L16.5,2.5zM7.5,21.5c-3.3,-1.5 -5.6,-4.7 -6.0,-8.5L0.1,13.0C0.6,19.2 5.7,24.0 12.0,24.0c0.2,0.0 0.4,0.0 0.7,0.0l-3.8,-3.8L7.5,21.5z\" /> </vector>";
string dp1= str;
dp1.replace(dp1.find("<?xml version=\"1.0\" encoding=\"utf-8\"?> <vector android:height=\"64.0dip\" android:width=\"64.0dip\" android:viewportWidth=\"24.0\" android:viewportHeight=\"24.0\" xmlns:android=\"http://schemas.android.com/apk/res/android\"> <path android:fillColor=\"#00000000\" android:pathData=\""), 269, "");
dp1.replace(dp1.find("/> <path android:fillColor=\"#*common:color/qs_toggles_color\" android:pathData=\"M15.05,10.25l0.0,-0.5c0.0,-1.66 -1.34,-3.0 -3.0,-3.0s-2.99,1.34 -2.99,3.0l-0.01,0.5c-0.55,0.0 -1.0,0.45 -1.0,1.0l0.0,5.0c0.0,0.55 0.45,1.0 1.0,1.0l6.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0l0.0,-5.0C16.05,10.7 15.6,10.25 15.05,10.25zM12.05,14.75c-0.55,0.0 -1.0,-0.45 -1.0,-1.0c0.0,-0.55 0.45,-1.0 1.0,-1.0s1.0,0.45 1.0,1.0C13.05,14.3 12.6,14.75 12.05,14.75zM14.05,10.25l-4.0,0.0l0.0,-0.5c0.0,-1.1 0.9,-2.05 2.0,-2.05s2.0,0.94 2.0,2.05L14.05,10.25z/> <path android:fillColor=\"#*common:color/qs_toggles_color\" android:pathData=\"M15.05,10.25l0.0,-0.5c0.0,-1.66 -1.34,-3.0 -3.0,-3.0s-2.99,1.34 -2.99,3.0l-0.01,0.5c-0.55,0.0 -1.0,0.45 -1.0,1.0l0.0,5.0c0.0,0.55 0.45,1.0 1.0,1.0l6.0,0.0c0.55,0.0 1.0,-0.45 1.0,-1.0l0.0,-5.0C16.05,10.7 15.6,10.25 15.05,10.25zM12.05,14.75c-0.55,0.0 -1.0,-0.45 -1.0,-1.0c0.0,-0.55 0.45,-1.0 1.0,-1.0s1.0,0.45 1.0,1.0C13.05,14.3 12.6,14.75 12.05,14.75zM14.05,10.25l-4.0,0.0l0.0,-0.5c0.0,-1.1 0.9,-2.05 2.0,-2.05s2.0,0.94 2.0,2.05L14.05,10.25z\" <path android:fillColor=\"#*common:color/qs_toggles_color\" android:pathData=\"M16.5,2.5c3.3,1.5 5.6,4.7 6.0,8.5L24.0,11.0C23.4,4.8 18.3,0.0 12.0,0.0c-0.2,0.0 -0.4,0.0 -0.7,0.0l3.8,3.8L16.5,2.5zM7.5,21.5c-3.3,-1.5 -5.6,-4.7 -6.0,-8.5L0.1,13.0C0.6,19.2 5.7,24.0 12.0,24.0c0.2,0.0 0.4,0.0 0.7,0.0l-3.8,-3.8L7.5,21.5z\" /> </vector>\""), 525, "");
std::cout << dp1 << endl;
system ("PAUSE");
return 0;
}
So basically, I want to extract those 3 strings mentioned above into their own strings. I was thinking I could extract them based on their starting character, which is M. Thanks
A good way to extract data from an XML file would be to use an XML parser. If your XML file changed, you would have problems with the manual search of strings you are trying to perform.
What XML parser should I use in C++?
Related
How to set c++ boost graphml node and edge id?
I am using the Boost graph to store a set of nodes and edges and then write it to a graphml format. Whatever I do, I cannot find a way to access or set the node id (n0, n1) or edge id (e0) attributes. It seems to be automatically set. Is there a way to access and set it manually ? <?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <key id="key0" for="node" attr.name="id" attr.type="int" /> <key id="key1" for="edge" attr.name="length" attr.type="double" /> <key id="key2" for="edge" attr.name="max_speed" attr.type="double" /> <key id="key3" for="node" attr.name="name" attr.type="string" /> <key id="key4" for="edge" attr.name="name" attr.type="string" /> <key id="key5" for="edge" attr.name="source" attr.type="int" /> <key id="key6" for="node" attr.name="station" attr.type="boolean" /> <key id="key7" for="edge" attr.name="target" attr.type="int" /> <key id="key8" for="node" attr.name="theta" attr.type="double" /> <key id="key9" for="node" attr.name="x" attr.type="double" /> <key id="key10" for="node" attr.name="y" attr.type="double" /> <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst"> <node id="n0"> <data key="key0">10000</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <node id="n1"> <data key="key0">10001</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <edge id="e0" source="n0" target="n1"> <data key="key1">6.95279e-310</data> <data key="key2">150</data> <data key="key4"></data> <data key="key5">-127787376</data> <data key="key7">21994</data> </edge> </graph> </graphml> My graph typedef typename boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, GpNode, GpEdge> DirectedGraph; Where GpNode and GpEdge are custom class definitions. Thanks in advance
write_graphml takes a dynamic_properties. Let's configure that: Live On Coliru #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphml.hpp> struct GpNode { int id; std::string name; bool station; double theta; double x; double y; }; struct GpEdge { double length; double max_speed; std::string name; int source; int target; }; using DirectedGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, GpNode, GpEdge>; int main() { std::ifstream ifs("input.xml"); DirectedGraph g; auto n0 = add_vertex( GpNode{ 10000, // id "node1", // name 0, // station 0, // theta 6.95279e-310, // x 0, // y }, g); auto n1 = add_vertex( GpNode{ 10001, // id "node1", // name 0, // station 0, // theta 6.95279e-310, // x 0, // y }, g); /*auto e0 = */add_edge(n0, n1, GpEdge{ 6.95279e-310, // length 150, // max_speed "", // name -127787376, // source 21994, // target }, g); auto vindex = get(&GpNode::id, g); boost::dynamic_properties dp; //dp.property("node_id", vindex); dp.property("id", vindex); dp.property("name", get(&GpNode::name, g)); dp.property("station", get(&GpNode::station, g)); dp.property("theta", get(&GpNode::theta, g)); dp.property("x", get(&GpNode::x, g)); dp.property("y", get(&GpNode::y, g)); dp.property("length", get(&GpEdge::length, g)); dp.property("max_speed", get(&GpEdge::max_speed, g)); dp.property("name", get(&GpEdge::name, g)); dp.property("source", get(&GpEdge::source, g)); dp.property("target", get(&GpEdge::target, g)); boost::write_graphml(std::cout, g, dp); } Prints <?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <key id="key0" for="node" attr.name="id" attr.type="int" /> <key id="key1" for="edge" attr.name="length" attr.type="double" /> <key id="key2" for="edge" attr.name="max_speed" attr.type="double" /> <key id="key3" for="node" attr.name="name" attr.type="string" /> <key id="key4" for="edge" attr.name="name" attr.type="string" /> <key id="key5" for="edge" attr.name="source" attr.type="int" /> <key id="key6" for="node" attr.name="station" attr.type="boolean" /> <key id="key7" for="edge" attr.name="target" attr.type="int" /> <key id="key8" for="node" attr.name="theta" attr.type="double" /> <key id="key9" for="node" attr.name="x" attr.type="double" /> <key id="key10" for="node" attr.name="y" attr.type="double" /> <graph id="G" edgedefault="directed" parse.nodeids="free" parse.edgeids="canonical" parse.order="nodesfirst"> <node id="n0"> <data key="key0">10000</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <node id="n1"> <data key="key0">10001</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <edge id="e0" source="n0" target="n1"> <data key="key1">6.95279e-310</data> <data key="key2">150</data> <data key="key4"></data> <data key="key5">-127787376</data> <data key="key7">21994</data> </edge> </graph> </graphml> Mmm. That took a while. But now I see. I know that write_graphviz_dp assumes node_id is the node id property, but as you can see, I tried and it didn't help Docs To The Rescue But, wait, docs show a second overload that also takes VertexIndexMap. Let's.... try that? boost::write_graphml(std::cout, g, vindex, dp); Now it prints Live On Coliru <?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <key id="key0" for="node" attr.name="id" attr.type="int" /> <key id="key1" for="edge" attr.name="length" attr.type="double" /> <key id="key2" for="edge" attr.name="max_speed" attr.type="double" /> <key id="key3" for="node" attr.name="name" attr.type="string" /> <key id="key4" for="edge" attr.name="name" attr.type="string" /> <key id="key5" for="edge" attr.name="source" attr.type="int" /> <key id="key6" for="node" attr.name="station" attr.type="boolean" /> <key id="key7" for="edge" attr.name="target" attr.type="int" /> <key id="key8" for="node" attr.name="theta" attr.type="double" /> <key id="key9" for="node" attr.name="x" attr.type="double" /> <key id="key10" for="node" attr.name="y" attr.type="double" /> <graph id="G" edgedefault="directed" parse.nodeids="free" parse.edgeids="canonical" parse.order="nodesfirst"> <node id="n10000"> <data key="key0">10000</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <node id="n10001"> <data key="key0">10001</data> <data key="key3">node1</data> <data key="key6">0</data> <data key="key8">0</data> <data key="key9">6.95279e-310</data> <data key="key10">0</data> </node> <edge id="e0" source="n10000" target="n10001"> <data key="key1">6.95279e-310</data> <data key="key2">150</data> <data key="key4"></data> <data key="key5">-127787376</data> <data key="key7">21994</data> </edge> </graph> </graphml> That's likely as close as you'll get with it. Changing the id type to std::string doesn't prevent the "n" prefix. (I suppose it's to allow edges to have id's colliding with nodes without problems?)
Sed (OS X) replace block of text containing given string with other block of text
I'd like to replace all lines containing Test.bundle (those lines are grouped in one block) with other files from <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\one.png" /> <BundleResource Include="Resources\Test.bundle\two.png" /> <BundleResource Include="Resources\Test.bundle\three.png" /> </ItemGroup> to <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\four.png" /> <BundleResource Include="Resources\Test.bundle\five.png" /> <BundleResource Include="Resources\Test.bundle\six.png" /> <BundleResource Include="Resources\Test.bundle\seven.png" /> </ItemGroup> What I did res=$(find Resources/Test.bundle -type f | sed 's/\\/\//g' | xargs -I {} echo "<BundleResource Include=\"{}\" />") #get new files, change path delimiters, wrap file names in output pattern sed -E -i '' '/Test\.bundle/,/ItemGroup/c\ BUNDLE_PLACEHOLDER' file.ext #remove whole block from first line containing Test.bundle to closing ItemGroup and replace with placeholder sed -E -i '' "s:BUNDLE_PLACEHOLDER:$res:" file.ext #replace with new block I couldn't change it in one pass in the third command due to "extra characters after \ at the end of c command" so I changed it to the string placeholder that I was trying to replace in the next command. That also failed due to unescaped newline inside substitute pattern that I'm currently trying to solve. There is also missing closing ItemGroup tag that will be added later. Are there any other options using sed? Can I catch only group containing Test.bundle without catching closing ItemGroup? How to escape newlines to satisfy the substitution pattern?
It's not clear what you're really trying to match on but this might be what you want: awk ' NR==FNR { new = new $0 ORS next } /Test\.bundle/ { printf "%s", new new = "" next } { print } ' new old e.g.: $ cat old <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\one.png" /> <BundleResource Include="Resources\Test.bundle\two.png" /> <BundleResource Include="Resources\Test.bundle\three.png" /> </ItemGroup> $ cat new <BundleResource Include="Resources\Test.bundle\four.png" /> <BundleResource Include="Resources\Test.bundle\five.png" /> <BundleResource Include="Resources\Test.bundle\six.png" /> <BundleResource Include="Resources\Test.bundle\seven.png" /> . $ awk ' NR==FNR { new = new $0 ORS next } /Test\.bundle/ { printf "%s", new new = "" next } { print } ' new old <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\four.png" /> <BundleResource Include="Resources\Test.bundle\five.png" /> <BundleResource Include="Resources\Test.bundle\six.png" /> <BundleResource Include="Resources\Test.bundle\seven.png" /> </ItemGroup>
First, sed isn't really your best option here, but since you asked for sed... Here's a crude first pass. $: cat new <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\four.png" /> <BundleResource Include="Resources\Test.bundle\five.png" /> <BundleResource Include="Resources\Test.bundle\six.png" /> <BundleResource Include="Resources\Test.bundle\seven.png" /> </ItemGroup> $: cat old stuff before ... more stuff <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\one.png" /> <BundleResource Include="Resources\Test.bundle\two.png" /> <BundleResource Include="Resources\Test.bundle\three.png" /> </ItemGroup> stuff after ... more stuff. $: sed -n '/<ItemGroup>/,/<[/]ItemGroup>/{ /<ItemGroup>/h; /<[/]ItemGroup>/{ H; s/^.*//; x; /Test[.]bundle/{ s/^.*/cat new/e; }; p; d; } H; d; }; p; ' old stuff before ... more stuff <ItemGroup> <BundleResource Include="Resources\some_other_file.json" /> <BundleResource Include="Resources\Test.bundle\four.png" /> <BundleResource Include="Resources\Test.bundle\five.png" /> <BundleResource Include="Resources\Test.bundle\six.png" /> <BundleResource Include="Resources\Test.bundle\seven.png" /> </ItemGroup> stuff after ... more stuff. This obviously makes some simple assumptions about your file structure. The same logic in awk: awk 'NR == FNR { new=new$0"\n"; next; } /<ItemGroup>/,/<[/]ItemGroup>/{ grp=grp$0"\n"; if ($0 ~ "</ItemGroup>") { if (grp ~ "Test.bundle") { print new } else { print grp } grp="" } else next; } 1' new old
How to convert vtkpolydata into vtkimagedata?
In vtp ( or xml? ) files I have a set of points with position (x,y,z), mass (m) and densities (rho) for each points. They look like so <?xml version="1.0"?> <VTKFile type="PolyData" version="0.1" byte_order="LittleEndian" header_type="UInt32" compressor="vtkZLibDataCompressor"> <PolyData> <Piece NumberOfPoints="524288" NumberOfVerts="0" NumberOfLines="0" NumberOfStrips="0" NumberOfPolys="0" > <PointData> <DataArray type="Float32" Name="vx" format="appended" RangeMin="-10617.716797" RangeMax="11650.322266" offset="0" /> <DataArray type="Float32" Name="vy" format="appended" RangeMin="-12008.198242" RangeMax="11676.560547" offset="2554076" /> <DataArray type="Float32" Name="vz" format="appended" RangeMin="-10880.447266" RangeMax="11361.508789" offset="5104080" /> <DataArray type="Float32" Name="mass" format="appended" RangeMin="0.16916139424" RangeMax="0.83083856106" offset="7655432" /> <DataArray type="Float32" Name="uu" format="appended" RangeMin="0" RangeMax="117252.91406" offset="7742064" /> <DataArray type="Float32" Name="hh" format="appended" RangeMin="0" RangeMax="4.1185030937" offset="8877700" /> <DataArray type="Float32" Name="mu" format="appended" RangeMin="1.2307692766" RangeMax="1.2307692766" offset="10032668" /> <DataArray type="Float32" Name="rho" format="appended" RangeMin="0" RangeMax="49503150080" offset="10038236" /> <DataArray type="Float32" Name="phi" format="appended" RangeMin="-1.3579902649" RangeMax="1.2645899057" offset="11265024" /> <DataArray type="Int64" Name="id" format="appended" RangeMin="0" RangeMax="524287" offset="13840232" /> <DataArray type="UInt16" Name="mask" format="appended" RangeMin="0" RangeMax="3" offset="15044924" /> </PointData> <CellData> </CellData> <Points> <DataArray type="Float32" Name="Points" NumberOfComponents="3" format="appended" RangeMin="0.89113022864" RangeMax="110.020575" offset="15133592" /> </Points> <Verts> <DataArray type="Int64" Name="connectivity" format="appended" RangeMin="" RangeMax="" offset="22080132" /> <DataArray type="Int64" Name="offsets" format="appended" RangeMin="" RangeMax="" offset="22080148" /> </Verts> <Lines> <DataArray type="Int64" Name="connectivity" format="appended" RangeMin="" RangeMax="" offset="22080164" /> <DataArray type="Int64" Name="offsets" format="appended" RangeMin="" RangeMax="" offset="22080180" /> </Lines> <Strips> <DataArray type="Int64" Name="connectivity" format="appended" RangeMin="" RangeMax="" offset="22080196" /> <DataArray type="Int64" Name="offsets" format="appended" RangeMin="" RangeMax="" offset="22080212" /> </Strips> <Polys> <DataArray type="Int64" Name="connectivity" format="appended" RangeMin="" RangeMax="" offset="22080228" /> <DataArray type="Int64" Name="offsets" format="appended" RangeMin="" RangeMax="" offset="22080244" /> </Polys> </Piece> </PolyData> <AppendedData encoding="base64"> ... </AppendedData> </VTKFile I would like to use this to do some volume rendering, therefore I need to have it as ImageData. My first stupid approach is this : using a vtkXMLImageDataReader instead of a vtkXMLPolyDataReader. It obviously didn't work. What can I do to convert it to ImageData or make it work with any volumeMapper? Thanks
With vtkplotter you can create a vtkVolume interpolating from a sparse set of points: from vtkplotter import * mymesh = ... # vtkPolyData with pointdata vol = interpolateToVolume(Actor(mymesh)) #write(vol, 'output.vti') show(vol) see here.
I might be missing something in the question. But from my understanding, you can simpy follow this example: link
Boost Read_graphml doesn't read xml properly it gives all the vertices but they are empty
I have a adjacency list of type boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData> Where GraphData is a structure contains name struct GraphItem { std::string Name; } I am able to write graph to xml void WriteGraph() { boost::dynamic_properties dp; dp.property("Name", make_transform_value_property_map(&Name, boost::get(vertex_bundle, graph))); boost::write_graphml(filename, graph, dp, true); } std::string Name(boost::vertex_bundle_type<Graph>::type v) { std::ostringstream oss; oss << v.Name; return oss.str(); } I get XML as <graphml> <key id="key0" for="node" attr.name="Name" attr.type="string" /> <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst"> <node id="n0"> <data key="key0">A</data> </node> <node id="n1"> <data key="key0">D</data> </node> <node id="n2"> <data key="key0">B</data> </node> <node id="n3"> <data key="key0">C</data> </node> <edge id="e0" source="n0" target="n1"> </edge> <edge id="e1" source="n2" target="n3"> </edge> </graph> </graphml> When I read graph void ReadGraph() { boost::dynamic_properties dp; std::ifstream file(fileName); boost::read_graphml(file, graph, dp); } This is crashing says property Name not found. If I use ignore_other_properties for property, boost::dynamic_properties dp(ignore_other_properties); It works but I am not getting any graph item in graph vertices.
The graph is not empty, you get: 0 --> 1 1 --> 2 --> 3 3 --> Or in XML: https://paste.ubuntu.com/p/c4tGmxGssJ/ Of course, you wanted to read the name property. For that you obviously need to register the property with the dynamic-properties map. Note You can access members of property bundles much simpler: dp.property("Name", boost::get(&GraphData::Name, graph)); Full Demo #include <boost/graph/adjacency_list.hpp> #include <boost/graph/graphml.hpp> struct GraphData { std::string Name; }; using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData>; Graph ReadGraph(std::string const& fileName) { Graph graph; boost::dynamic_properties dp; dp.property("Name", boost::get(&GraphData::Name, graph)); std::ifstream file(fileName); boost::read_graphml(file, graph, dp); return graph; } void WriteGraph(std::ostream& os, Graph& graph) { boost::dynamic_properties dp; dp.property("Name", get(&GraphData::Name, graph)); boost::write_graphml(os, graph, dp, true); } #include <boost/graph/graph_utility.hpp> int main() { Graph g = ReadGraph("input.txt"); print_graph(g, get(&GraphData::Name, g)); // or as XML WriteGraph(std::cout << "==== XML version: ====\n\n", g); } Prints A --> D D --> B --> C C --> ==== XML version: ==== <?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <key id="key0" for="node" attr.name="Name" attr.type="string" /> <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst"> <node id="n0"> <data key="key0">A</data> </node> <node id="n1"> <data key="key0">D</data> </node> <node id="n2"> <data key="key0">B</data> </node> <node id="n3"> <data key="key0">C</data> </node> <edge id="e0" source="n0" target="n1"> </edge> <edge id="e1" source="n2" target="n3"> </edge> </graph> </graphml>
Overwrite an existing text file c++
This is how my Save As works - it is copying the current file's lines until it reaches the first figure and then I use my print methods to print the figure's info and then close the tag. std::ofstream newFile(filePath1_fixed, std::ios::app); std::fstream openedFile(filePath); std::string line1; while (std::getline(openedFile, line1)) { if (line1.find("<rect") != std::string::npos || line1.find("<circle") != std::string::npos || line1.find("<line") != std::string::npos) break; newFile << line1 << std::endl; } figc.printToFile(newFile); newFile << "</svg>\n"; My question is how to save the changes to the current file? I tried something like this: std::ifstream openedFile(filePath); std::ofstream newFile(filePath, std::ios::app); std::string line1; std::string info_beg[100]; int t = 0; while (std::getline(openedFile, line1)) { std::cout << "HELLYEAH"; if (line1.find("<rect") != std::string::npos || line1.find("<circle") != std::string::npos || line1.find("<line") != std::string::npos) break; info_beg[t++] = line1; } for (int i = 0; i < t; i++) newFile << info_beg[i] << std::endl; figc.printToFile(newFile); newFile << "</svg>\n"; This is the nearest I've gone. I get this: <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example rect01 - rectangle with sharp corners</desc> <!-- Show outline of canvas using 'rect' element --> <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2" /> <line x1="20" y1="100" x2="100" y2="20" stroke="red" stroke-width="2" /> <rect x="20" y="30" width="40" height="50" fill="red" stroke="red" stroke-width="1" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="1" /> <line x1="100" y1="200" x2="300" y2="400" stroke="red" stroke-width="2" /> <circle cx="10" cy="20" r="30" fill="red" stroke="blue" stroke-width="2" /> </svg> <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1"> <desc>Example rect01 - rectangle with sharp corners</desc> <!-- Show outline of canvas using 'rect' element --> <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2" /> <line x1="20" y1="100" x2="100" y2="20" stroke="red" stroke-width="2" /> <rect x="20" y="30" width="40" height="50" fill="red" stroke="red" stroke-width="1" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="1" /> <line x1="100" y1="200" x2="300" y2="400" stroke="red" stroke-width="2" /> <circle cx="10" cy="20" r="30" fill="red" stroke="blue" stroke-width="2" /> <rect x="10" y="20" width="30" height="40" fill="red" stroke="blue" stroke-width="2" /> </svg> So my actual question is how to delete the first or overwrite it or I need a different approach.
Use ios::trunc instead of ios::app Using std::ios::app in the constructor for your std::ofstream tells the program to append to the file and not overwrite it. If you want to overwrite it (ie truncate), then using std::ios::trunc will tell the program to overwrite the existing file. ofstream does this by default, so you could just write the initialization as just std::ofstream newFile(filePath);. Also, don't try to read the file and write to it at the same time; that won't work. Use ifstream to get the data into the buffer, then use close() to close the file. Then initialize newFile to overwrite the file and write out the buffer.