saving simple XML files - c

I started using XML format to create file, for this purpose I use this code :
void xml_create_file()
{
mxml_node_t *xml;
mxml_node_t *data;
FILE *f;
xml = mxmlNewXML("1.0");
data = mxmlNewElement(xml, "setting");
data = mxmlNewElement(xml, "URL");
data = mxmlNewText(data, 0, "http://192.168.55.55");
f = fopen("/etc/share/backup.xml", "wb");
if (f==NULL) {
close(f);
printf("backup could not be written.\n");
}
else {
mxmlSaveFile(xml, f, MXML_NO_CALLBACK);
close(f);
mxmlDelete(data);
mxmlDelete(xml);
printf("backup Saved\n");
}
}
when I check the file /etc/share/backup.xml, I found it empty !!!
how to resolve this problem ?
note : I use microxml lib

close(f)
should be
fclose(f)
(The compiler should have warned you about this.)

Related

How can i edit specific part of line in a text file in C?

Let's say that I have a .txt file which contains these two lines:
Item="1" Name="Sword" Damage="2.5"
Item="2" Name="Axe" Damage="3"
How can i change the damage of the Axe to 3.5 in the text file with C?
EDITED: this is how i read each line of the text file, and I'm filling a gtk list store with the text info, the dhd_LocalizaItem its a function to get what is inside the " " e.g. Item="1", i will catch the 1 with that function, but all gtk thing its working fine, as I said, i want now a C function/command to edit specific part of a line in a text file.
void get_message() {
GtkTreeIter dhd_iter;
FILE * dhd_pFile;
char dhd_G_CodProduto[256];
char dhd_G_NomeProduto[256];
char dhd_contaItem[16];
char dhd_quantidade[32];
char dhd_valorItem[32];
char dhd_getbuf[1024];
dhd_chekDel = 0;
dhd_pFile = fopen ("Logs/logCancelar.txt", "r");
if(dhd_pFile == NULL) {
printf("Erro! Nao foi possivel abrir o log de cancelamento!\n");
}
else {
while( (fgets(dhd_getbuf, sizeof(dhd_getbuf), dhd_pFile))!=NULL ) {
dhd_LocalizaItem (dhd_getbuf, dhd_stringItem);
dhd_restou = dhd_LocalizaItem( "Item=" , dhd_getbuf);
strcpy(dhd_contaItem,dhd_restou);
dhd_LocalizaItem (dhd_getbuf, dhd_strong);
dhd_restou = dhd_LocalizaItem( "CodProduto=" , dhd_getbuf);
strcpy(dhd_G_CodProduto,dhd_restou);
dhd_LocalizaItem (dhd_getbuf, dhd_strung);
dhd_restou = dhd_LocalizaItem( "NomeProduto=" , dhd_getbuf);
strcpy(dhd_G_NomeProduto,dhd_restou);
dhd_LocalizaItem (dhd_getbuf, dhd_streng);
dhd_restou = dhd_LocalizaItem( "Quantidade=" , dhd_getbuf);
strcpy(dhd_quantidade,dhd_restou);
dhd_LocalizaItem (dhd_getbuf, dhd_stringTotal);
dhd_restou = dhd_LocalizaItem( "ValorTotal=" , dhd_getbuf);
strcpy(dhd_valorItem,dhd_restou);
gtk_list_store_append(GTK_LIST_STORE( mainWindowObjects.liststore ), &dhd_iter);
gtk_list_store_set(GTK_LIST_STORE( mainWindowObjects.liststore ), &dhd_iter,
ITEM, dhd_contaItem,
CODIGO, dhd_G_CodProduto ,
DESCRICAO, dhd_G_NomeProduto ,
QTD, dhd_quantidade,
VALOR, dhd_valorItem,
-1 );
}
}
fclose(dhd_pFile);
}
And sorry for my bad english everyone.
#include <stdio.h>
#include <string.h>
typedef struct arms {
int id;
char name[32];
double damage;
} Arms;
int read_arms(Arms *a, FILE *fp){
return fscanf(fp, " Item=\"%d\" Name=\"%[^\"]\" Damage=\"%lf\"",
&a->id, a->name, &a->damage);
}
void write_arms(Arms *a, FILE *fp){
fprintf(fp, "Item=\"%d\" Name=\"%s\" Damage=\"%3.1f\"\n",
a->id, a->name, a->damage);
}
#define ARMSFILE "arms.dat"
void change_damage_by_name(const char *name, double damage){
FILE *fin, *fout;
Arms a;
fin = fopen(ARMSFILE, "r");
fout = fopen("arms.tmp", "w");
while(EOF!=read_arms(&a, fin)){
if(strcmp(a.name, name)==0)
a.damage = damage;
write_arms(&a, fout);
}
fclose(fin);
fclose(fout);
remove(ARMSFILE);
rename("arms.tmp", ARMSFILE);
}
int main(void){
change_damage_by_name("Axe", 3.5);
return 0;
}
Probably try to make some sort of javascript script. I never tried making scripts outside of website / HTML/CSS related, but here's my idea.
Make a file named edit.js
Open it [with] notepad, notepad++, or some sort of coding editor preferably. Notepad works, but Notepad++ I recommend ; its free.
In reality, JavaScript isn't allowed to write, modify, or edit any file, only read them; This is due to security [and probably legal] reasons. So this is what I'd recommend:
Step One: Upload your text file and a new javascript file to a online hosting, or if I can think this out correctly, just make it on your harddrive in a folder.
Convert the text file into a .html format, which can be done by:
Save As > File Type: All File Types > File name: mytextdocument.html
And also creating a .js file with it, by doing the same thing with notepad.
The html file should include something on the lines of this.
<html>
<head>
<title>My Text Document</title>
<script src="myscript.js"></script>
</head>
<body id="body" onLoad="replaceItem(); saveTextAsFile();">
<div id="content">
<ul>
<li id="1" value="sword">Item="1" Name="Sword" Damage="2.5"</li>
<li id="2" value="axe">Item="2" Name="Axe" Damage="3"</li>
</ul>
</div>
</body>
</html>
The .js file should be on the lines of this;
function replaceItem() {
var x = document.getElementById("2");
x.innerHTML = "Item='2' Name='Axe' Damage='3.5'";
}
function saveTextAsFile()
{
var textToWrite = document.getElementById("content").innerHTML;
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = "items.txt";
var downloadLink = document.createElement("a");
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = "Download File";
if (window.webkitURL != null)
{
// Chrome allows the link to be clicked
// without actually adding it to the DOM.
downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
}
else
{
// Firefox requires the link to be added to the DOM
// before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
NOTE that before opening that HTML file, to make sure that you edit the content from the JavaScript file to what you want.

Returning multiple file pointers in C

I'm new to C and would like some help with an issue I have. I'm reading and writing to pipes as follows:
f = fdopen(fdH2P[WRITE], "w"); // writing to pipe, returns a file pointer
and
r = fdopen(fdP2H[READ], "r"); // reading from pipe
I want to return both these file pointers from my function. What's the best way to do that?
You can either put the two file pointers into a structure and return that, or you can pass pointers to the function, like this
void GetPipes( FILE **wptr, FILE **rptr )
{
*wptr = fdopen(fdH2P[WRITE], "w");
*rptr = fdopen(fdP2H[READ], "r");
}
void SomeOtherFunction( void )
{
FILE *wptr, *rptr;
GetPipes( &wptr, &rptr );
...
}
You can return a struct:
Define struct, with typedef for convenience
typedef struct dual_fp {
FILE *read_fp;
FILE *write_fp;
} dual_fp;
Add function to open two files
dual_fp dual_fdopen(int write_fd, int read_fd) {
dual_fp ret;
// review error handling and reporting,
// such as add error code fields to struct dual_fp,
// and possibly do not open 2nd / close 1st file if the other fails
ret.write_fp = fdopen(write_fd, "w");
if (!ret.write_fp) perror("dual_fdopen for write");
ret.read_fp = fdopen(read_fd, "r");
if (!ret.read_fp) perror("dual_fdopen for read");
return ret;
}
Call it
dual_fp fps = dual_fdopen(fdH2P[WRITE], fdopen(fdP2H[READ]);
// use fps.read_fp and fps.write_fp after checking they are not NULL
Create a struct and return an instance of the struct.
typedef struct
{
FILE* write;
FILE* read;
} FilePointers;
FilePointers foo()
{
// Assuming you have access to the data...
FILE* w = fdopen(fdH2P[WRITE], "w");
FILE* r = fdopen(fdP2H[READ], "r");
FilePointers fp = {w, r};
return fp;
}

How to read multiple images from a folder in open cv (using C)

I am new to open CV and C. How do i specify multiple images for the same kind of operation.
if your images are (sequentially) numbered, you could abuse a hidden feature with VideoCapture, just pass it a (format) string:
VideoCapture cap("/my/folder/p%05d.jpg"); // would work with: "/my/folder/p00013.jpg", etc
while( cap.isOpened() )
{
Mat img;
cap.read(img);
// process(img);
}
OpenCV doesn't provide any functionality for this. you can use a third party lib for reading the files from the file system. in case your images are sequentially numbered you can use #berak technique but if your files are not sequential then use can use boost::filesystem (heavy and my favorite) for reading the file. or dirent.h (small, single header only) library.
Following code uses dirent.h for this job
#include <iostream>
#include <opencv2\opencv.hpp>
#include "dirent.h"
int main(int argc, char* argv[])
{
std::string inputDirectory = "D:\\inputImages";
std::string outputDirectory = "D:\\outputImages";
DIR *directory = opendir (inputDirectory.c_str());
struct dirent *_dirent = NULL;
if(directory == NULL)
{
printf("Cannot open Input Folder\n");
return 1;
}
while((_dirent = readdir(directory)) != NULL)
{
std::string fileName = inputDirectory + "\\" +std::string(_dirent->d_name);
cv::Mat rawImage = cv::imread(fileName.c_str());
if(rawImage.data == NULL)
{
printf("Cannot Open Image\n");
continue;
}
// Add your any image filter here
fileName = outputDirectory + "\\" + std::string(_dirent->d_name);
cv::imwrite(fileName.c_str(), rawImage);
}
closedir(directory);
}

Parse a GML file (from a shp one) in C

My problem is that, using ogr2ogr, I parse a shp file into a gml one.
Then I want to parse this file in my C function.
sprintf(buffer, "PATH=/Library/Frameworks/GDAL.framework/Programs:$PATH:/usr/local/bin ogr2ogr -f \"GML\" files/Extraction/coord.gml %s", lectureFichier);
system(buffer);
sprintf(buff, "sed \"2s/.*/\\<ogr:FeatureCollection\\>/\" files/Extraction/coord.gml | sed '3,6d' > files/Extraction/temp.xml");
system(buff);
FILE *fichier = NULL;
FILE *final = NULL;
fichier = fopen("files/Extraction/temporaire.csv", "w+");
xmlDocPtr doc;
xmlChar *xpath = (xmlChar*) "//keyword";
xmlNodeSetPtr nodeset;
xmlXPathContextPtr context;
xmlXPathObjectPtr result;
int i;
doc = xmlParseFile("files/Extraction/temp.xml");
When I execute the program, I have an error for every line because of the namespace prefix (gml or ogr) that are not defined)
Example of temp.xml
<ogr:FeatureCollection>
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>847001.4933830451</gml:X><gml:Y>6298087.567566251</gml:Y></gml:coord>
<gml:coord><gml:X>859036.8755179688</gml:X><gml:Y>6309720.622619263</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
Do you have an idea of how to make the program know these new namespace?
EDIT:
xmlDocPtr doc;
xmlChar *xpath = (xmlChar*) "//keyword";
xmlNodeSetPtr nodeset;
xmlXPathContextPtr context;
xmlXPathRegisterNs(context, "ogr", "http://ogr.maptools.org/");
xmlXPathRegisterNs(context, "gml", "http://www.opengis.net/gml");
xmlXPathObjectPtr result;
int i;
doc = xmlParseFile("files/Extraction/temp.xml");
if (doc == NULL ) {
fprintf(stderr,"Document not parsed successfully. \n");
return 0;
}
context = xmlXPathNewContext(doc);
if (context == NULL) {
printf("Error in xmlXPathNewContext\n");
return 0;
}
xpath = "//gml:coordinates/text()";
result = xmlXPathEvalExpression(xpath, context);
xmlXPathFreeContext(context);
if (result == NULL) {
printf("Error in xmlXPathEvalExpression\n");
return 0;
}
if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
xmlXPathFreeObject(result);
printf("No result\n");
return 0;
}
`
When adding what you've given me, I'm having a Seg Fault and I really don't know where it's from, but it seems i'm getting closer to the answer.
Do you have an idea where I'm wrong?
I would think you just need to add the namespace declarations to the FeatureCollection element, so it looks like this:
<ogr:FeatureCollection
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
You can assumedly do that in your sed script.
When trying to query namespaced elements with xpath you need to register your namespaces first. So you might need to do something like this:
xmlXPathRegisterNs(context, "ogr", "http://ogr.maptools.org/")
xmlXPathRegisterNs(context, "gml", "http://www.opengis.net/gml")
Then when you're trying to query a gml or ogr element, you would do so like this:
xpath = "//gml:coordinates/text()";
xmlXPathEvalExpression(xpath, context);

Problem in retrieving the ini file through web page

I am using an .ini file to store some values and retrieve values from it using the iniparser.
When I give (hardcode) the query and retrive the value through the command line, I am able to retrive the ini file and do some operation.
But when I pass the query through http, then I am getting an error (file not found), i.e., the ini file couldn't be loaded.
Command line :
int main(void)
{
printf("Content-type: text/html; charset=utf-8\n\n");
char* data = "/cgi-bin/set.cgi?pname=x&value=700&url=http://IP/home.html";
//perform some operation
}
Through http:
.html
function SetValue(id)
{
var val;
var URL = window.location.href;
if(id =="set")
{
document.location = "/cgi-bin/set.cgi?pname="+rwparams+"&value="+val+"&url="+URL;
}
}
.c
int * Value(char* pname)
{
dictionary * ini ;
char *key1 = NULL;
char *key2 =NULL;
int i =0;
int val;
ini = iniparser_load("file.ini");
if(ini != NULL)
{
//key for fetching the value
key1 = (char*)malloc(sizeof(char)*50);
if(key1 != NULL)
{
strcpy(key1,"ValueList:");
key2 = (char*)malloc(sizeof(char)*50);
if(key2 != NULL)
{
strcpy(key2,pname);
strcat(key1,key2);
val = iniparser_getint(ini, key1, -1);
if(-1 == val || 0 > val)
{
return 0;
}
}
else
{
//error
free(key1);
return;
}
}
else
{
printf("ERROR : Memory Allocation Failure ");
return;
}
}
else
{
printf("ERROR : .ini File Missing");
return;
}
iniparser_freedict(ini);
free(key1);
free(key2);
return (int *)val;
}
void get_Value(char* pname,char* value)
{
int result =0;
result = Value(pname);
printf("Result : %d",result);
}
int main(void)
{
printf("Content-type: text/html; charset=utf-8\n\n");
char* data = getenv("QUERY_STRING");
//char* data = "/cgi-bin/set.cgi?pname=x&value=700&url=http://10.50.25.40/home.html";
//Parse to get the values seperately as parameter name, parameter value, url
//Calling get_Value method to set the value
get_Value(final_para,final_val);
}
*
file.ini
*
[ValueList]
x = 100;
y = 70;
When the request is sent through html page, I am always getting .ini file missing. If directly the request is sent from C file them it works fine.
How to resolve this?
Perhaps you have a problem with encoding of the URL parameters? You can't just pass any arbitrary string through a URL - there are some characters that must be encoded. Read this page about URL encoding.
Showing the value of the data string in your C program could be of great help with solving your problem.
Update:
There could be a difference as to where your program executes when called by the web server or directly by you. Are you sure it's being executed with the same "current directory". Chances are it's different, and thus when you attempt to open the ini file you fail. Try to print out the current directory (i.e. using the getcwd function) and compare both cases.

Resources