I am working in C, on Windows 11 and trying to send a POST request to an API. The request body should be in JSON format. Thus I just installed json-c. In Python, I know that json.dumps() created valid JSON strings that can be POSTed. For example:
text = 'στελιοσ'
json.dumps(text)
gives: '"\\u03c3\\u03c4\\u03b5\\u03bb\\u03b9\\u03bf\\u03c3"'
So, in lib-c I am doing:
#include <json.h>
#include <stdio.h>
void main()
{
char* text = "{\"key\":\"στελιοσ\"}";
struct json_object* jobj;
jobj = json_tokener_parse(text);
printf("jobj from str:\n---\n%s\n---\n", json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_PLAIN));
}
and I get:
jobj from str:
---
{ "key": "???????" }
---
So, how can I get these escaped Greek characters in C, just like the appear in Python via json.dumps()?
Thanks in advance.
Related
I am using PostgreSQL 9.5 64bit version on windows server.
The character encoding of the database is set to UTF8.
I'd like to create a function that manipulates multibyte strings.
(e.g. cleansing, replace etc.)
I copied C language logic for manipulating characters from a other system,
The logic assumes that the character code is sjis.
I do not want to change C language logic, so I want to convert from UTF8 to sjis in C language function of Postgresql.
Like the convert_to function. (However, since the convert_to function returns bytea type, I want to obtain it with TEXT type.)
Please tell me how to convert from UTF 8 to sjis in C language.
Create Function Script:
CREATE FUNCTION CLEANSING_STRING(character varying)
RETURNS character varying AS
'$libdir/MyFunc/CLEANSING_STRING.dll', 'CLEANSING_STRING'
LANGUAGE c VOLATILE STRICT;
C Source:
#include <stdio.h>
#include <string.h>
#include <postgres.h>
#include <port.h>
#include <fmgr.h>
#include <stdlib.h>
#include <builtins.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
extern PGDLLEXPORT Datum CLEANSING_STRING(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(CLEANSING_STRING);
Datum CLEANSING_STRING(PG_FUNCTION_ARGS)
{
// Get Arg
text *arg1 = (text *)PG_GETARG_TEXT_P(0);
// Text to Char[]
char *arg;
arg = text_to_cstring(arg1);
// UTF8 to Sjis
//Char *sjisChar[] = foo(arg); // something like that..
// Copied from other system.(Assumes that the character code is sjis.)
cleansingString(sjisChar);
replaceStrimg(sjisChar);
// Sjis to UTF8
//arg = bar(sjisChar); // something like that..
//Char[] to Text and Return
PG_RETURN_TEXT_P(cstring_to_text(arg));
}
Succeeded in the way I was taught by question comments.
#include <mb/pg_wchar.h> //Add to include.
...
Datum CLEANSING_STRING(PG_FUNCTION_ARGS)
{
// Get Arg
text *arg1 = (text *)PG_GETARG_TEXT_P(0);
// Text to Char[]
char *arg;
arg = text_to_cstring(arg1);
// UTF8 to Sjis
Char *sjisChar[] = pg_server_to_any(arg, strlen(arg), PG_SJIS);
// Copied from other system.(Assumes that the character code is sjis.)
cleansingString(sjisChar);
replaceStrimg(sjisChar);
// Sjis to UTF8
arg = pg_any_to_server(sjisChar, strlen(sjisChar), PG_SJIS); //It converts from SJIS to server (UTF 8), the third argument sets the encoding of the conversion source.
//Char[] to Text and Return
PG_RETURN_TEXT_P(cstring_to_text(arg));
}
I need to parse manually, without external libraries, a JSON message coming from a server, in C language.
The message coming from server would be like:
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 72[CR+LF]
}[CR+LF]
or
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 150[CR+LF]
}[CR+LF]
I need the number after STP:. The number is different in each message structure, so I need to get that number from the JSON structure. I can't use external libraries because this code is in an embedded system and exernal code is not allowed.
I tried this following:
int main (){
const char response_message[35] = "{\r\n\"Tmg\":\"R\",\r\n\"STP\":72,\r\n}";
const char needle[8] = "P\":";
char *ret;
ret = strstr(response_message, needle);
printf("The number is: %s\n", ret);
return 0;
}
But obviously, I am getting this result:
The number is: P":72,
}
So I need to only get the number, how can I get this?
Thanks
You can use a hacked solution. Use strstr () to find "STP": then find the following , or } and extract the digits in between.
And that's a hack. Not guaranteed to work. For something that's guaranteed to work, you use a JSON parser.
Trying out Google protocol buffers for my code in C language.
messagefile.proto
===================
mesage othermessage
{
optional string otherstring = 1;
}
message onemessage
{
optional string messagestring = 1;
optional int32 aninteger = 2;
optional othermessage otr_message= 3;
}
==============================================
--> protoc-c messagefile.proto --c_out=./
this resulted in two files
--> messagefile.pb-c.c and messagefile.pb-c.h
Now my code file which would try to use the
simpleexample.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "messagefile.pb-c.h"
#include <stdbool.h>
int main(int argc, const char * argv[])
{
onemessage msg = ONE__MESSAGE__INIT; //from generated .h code file
void *buf;
unsigned int len;
char *ptr;
//integer initialization
msg.has_aninteger = true;
msg.aninteger = 1;
//accessing the string in onemessage
msg.messagestring = malloc(sizeof("a simple string"));
strncpy(msg.messagestring,"a simple string",strlen("a simple string"));
//trying to initialize the string in the nested structure othermessage
msg.otr_message = malloc(sizeof(othermessage));
msg.otr_message->otherstring = malloc(sizeof("a not so simple string"));
strncpy(msg.otr_message->otherstring,"a not so simple string",strlen("a not so simple string"));
//lets find the length of the packed structure
len = one_message__get_packed_size(&msg); //from generated .h code
//lets arrange for as much size as len
buf = malloc(len);
//lets get the serialized structure in buf
one_message__pack_to_buffer(&msg,buf); //from generated code
//write it to a stream, for now the screen
fwrite(buf,len,1,stdout);
//free buffer
free(buf);
return 0;
}
I compile it as gcc -o testout messagefile.pb-c.c simpleexample.c -lprotobuf-c
The Problem I am facing is when trying to initialize the nested othermessage variables and then call the get_packed_size it throws a segmentation fault.
I tried various combinations and I can say that whenever having strings in a nested class, I am facing problem to access those using google protoc.
Am i missing something? Is there anything wrong.
Can anyone please help.
note:There might be a few general syntax errors please ignore them.
ThankYou.
note:There might be a few general syntax errors please ignore them.
Err... they are kinda hard to ignore since your code does not compile :-)
Anyway, apart from the syntax errors, you need to make several corrections to your code. In order to use the field otr_message, it is not sufficient to just malloc() it. You also need to initialize it so the headers in the message get the right values. This is done with init(), like this:
//trying to initialize the string in the nested structure othermessage
msg.otr_message = malloc(sizeof(othermessage));
othermessage__init(msg.otr_message);
Then you use the wrong function to do the packing to your own array. As explained here, you need to use pack() as opposed to pack_to_buffer(), like this:
//lets get the serialized structure in buf
onemessage__pack(&msg,buf); //from generated code
Finally, your strncpy() invocations have a mistake. The length calculated with strlen() does not include the null terminator, which you do need. So you need to take strlen()+1 or use sizeof(), like this:
strncpy(msg.messagestring,"a simple string",sizeof("a simple string"));
After making those changes, the example worked for me:
$ ./testout
a simple string
a not so simple string
is there an elegant way of parsing .conf file in a c program? say, if i have normal text file -
param1 = 22
param2 = 99
param34 = 11
param11 = 15
...
it'd be nice to get access in one function call, smth like:
int c = xfunction(my.conf, param34);
and now c = 11. Many thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#define xfunction(file, param) \
system("awk '/^" #param " = [0-9]+$/{ num = $3 };END { exit num }' " #file)
int main(void){
int c = xfunction(my.conf, param34);
printf("%d\n", c);
return 0;
}
It is better if you use a linked list as follow
struct node
{
char *key;
int value;
};
and assign all the key value pair to node and you can add as many node during parsing of conf file to the linked list.
later when you search you can simply traverse the linked list and check for the key by a simple strcmp() and get the value.
I'm implementing SIP protocol and I'm stuck while parsing SIP message. I'm using the oSIP library. My code is like that:
#include <stdio.h>
#include <stdlib.h>
#include <osip2/osip.h>
#include <osipparser2/osip_parser.h>
#include <string.h>
void main()
{
int i,error;
osip_message_t *message;
char text[]="INVITE sip:jarsku#feanor.pc.lut.fi SIP/2.0\nCall-ID: 123456789#aradan\nVia: SIP/2.0/UDP 157.24.25.137:5060\nFrom: Arto <sip:athamala#feanor.pc.lut.fi>\nTo: Jari <sip:jarsku#feanor.pc.lut.fi>\nCSeq: 1 INVITE\nContent-Type: application/sdp\n\nv=0\na=3333aaa333";
char *p=(char *)&text;
i = strlen(text);
error = osip_init(&message);
error = osip_message_init(&message);
error = osip_message_parse(message, p, i);
}
When I run this code, the message structure is filled with data from text. Respective the fields call_id, content_lenght, content_type, cseq, from, req_uri, sip_method, sip_version, to and vias are filled correctly, but in the field message is value 0x0, message_length is 0 and message_property is 2.
Error codes are 0 for all three commands.
Why is the message body not parsed ? I'm confused of this things:
In RFC is stated, that every line should be ended with CLRF sequence, but I'm simply using \n and it seems like working.
Next I dont like this statement:
error = osip_init(&message);
error = osip_message_init(&message);
For me, is this weird. In the documentation of oSIP is stated that sequence of:
osip_message_t *sip;
osip_message_init(&sip);
osip_message_parse(sip, buffer, length_of_buffer);
osip_message_free(sip);
should be enough (in my code I'm using init and message_init), but this is throwing me a Segmentation fault.
And why is possible, that the field content_length is autofilled but the message is not parsed ?
Last question : why is this topic so terribly covered on Internet ? No manuals, oSIP documentation is bad
Thank you
I think you might be reading the documentation wrong. The function osip_init() wants a osip_t **osip not a message. Re: http://www.gnu.org/software/osip/doc/html/group_howto0_initialize.html
osip_init is not needed to use just the parser, but you should init the parser with parser_init(); instead.
I got the same error as Matka mentioned in his comment.
return value -5 from osip_message_parse
It was due to a malformed sip message that I was passing to the program while debugging.