I want to trim this string below (which is a log.txt file) into the substring below.
Since there are no delimeters, I can't use strtok().
So how could I do it?
Log file's contents:
[INFO][2019-10-2323:21:45.638]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0001"}
[INFO][2019-10-2323:22:11.936]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0001"}
[INFO][2019-10-2323:22:29.232]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0002"}
[INFO][2019-10-2323:22:29.256]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0002"}
[INFO][2019-10-2323:22:33.192]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0003}
[INFO][2019-10-2323:22:48.075]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0003"}
[INFO][2019-10-2323:22:48.098]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0004"}
[INFO][2019-10-2323:22:52.034]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0004"}
[INFO][2019-10-2323:25:58.509]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0005"}
[INFO][2019-10-2323:26:42.425]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0005"}
[INFO][2019-10-2323:27:15.467]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0006"}
[INFO][2019-10-2323:27:42.030]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0006"}
[INFO][2019-10-2323:32:45.088]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0033"}
[INFO][2019-10-2323:33:11.934]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0007"}
[INFO][2019-10-2323:36:39.262]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0008"}
[INFO][2019-10-2323:36:39.267]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0008"}
[INFO][2019-10-2323:36:39.267]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0022"}
[INFO][2019-10-2323:36:39.332]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0009"}
The substring I want to find is the raw data's value, for example: FFA2010401000000
This should work to extract the raw data, assuming it's hex-encoded data (error checking, memory freeing, and proper headers are omitted for clarity):
#define RAW_STR ",\"raw\":\""
FILE *logfile = fopen( filename, "rb" );
char *line = NULL;
size_t len = 0;
for ( ;; )
{
ssize_t bytesRead = getline( &line, &len, logfile );
if ( bytesRead == -1 )
{
break;
}
char *rawData = strstr( line, RAW_STR );
if ( !raw )
{
continue;
}
// jump over the "raw":" string to the actual value
rawData += strlen( RAW_STR );
// assume the data is hex
unsigned long long value = strtoull( rawData, NULL, 16 );
...
}
This simple method depends on the log file being consistently formatted. If the log file doesn't always have the RAW_STR in that exact format, it won't work.
I've also assumed you're running on a POSIX system and have access to getline().
You might find regular expression useful in this scenario. Specifically regexec seems appropriate here.
int regexec(const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
Or a proper json parser. Checkout the c library section on the json format description website.
I`m writing the VB.net and need to call API(c language DLL)
My test sample code as follow
//Read Source File
char *SourceFilePath = "C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml";
FILE *sourcefile= fopen(SourceFilePath, "rb");
if (!sourcefile)
{
printf("Error=%s\n", *SourceFilePath);
return;
}
fseek(sourcefile,0,SEEK_END);
long src_ch_len = ftell(sourcefile);
rewind(sourcefile);
unsigned char *src_ch =(unsigned char*)malloc(sizeof(char)*src_ch_len);
result = fread(src_ch,1,src_ch_len,sourcefile);
if(result!=src_ch_len)
{
printf("Reading Error=%s\n", *sourcefile);
return;
}
fclose(sourcefile);
//Read Data File
//Skip...
rc = BasicVerify(algorithm, data, dataLen, key, signature, signatureLen);
API Function definition
unsigned long verify(unsigned long algorithm, unsigned char *data, int dataLen,unsigned char *signature, int signatureLen, char *cerFile)
How to convert fopen(SourceFilePath, "rb") and fread(src_ch,1,src_ch_len,sourcefile) to VB.NET
Thanks
The analogue to fopen using the modes "rb" in VB .NET appears to be the FileStream class using the FileAccess.Read mode. From there you can use the FileStream.Read method as an analogue for fread. For example:
dim sourceFile as FileStream
sourceFile = new FileStream("C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml", FileAccess.Read)
dim result as Integer
result = sourceFile.Read(array, 0, array.Length)
However, it seems from the fseek followed by ftell in your C code, you want to read the entire file into memory. This is often frowned upon since a file could be many gigabytes in size. If you really want to do that, use the File.ReadAllBytes method, for example:
dim src_ch as Byte()
src_ch = File.ReadAllBytes("C:\\Docs\\Scandi\\attach\\verifyTest\\center.xml")
hi i have used libpng to convert grayscale png image to raw image using c. in that lib the function png_init_io needs file pointer to read the png. but i pass the png image as buffer is there any other alternative functions to to read png image buffer to raw image. please help me
int read_png(char *file_name,int *outWidth,int *outHeight,unsigned char **outRaw) /* We need to open the file */
{
......
/* Set up the input control if you are using standard C streams */
png_init_io(png_ptr, fp);
......
}
instead i need this like
int read_png(unsigned char *pngbuff, int pngbuffleng, int *outWidth,int *outHeight,unsigned char **outRaw) /* We need to open the file */
{
}
From the manual of png_init_io, it is apparent that you can override the read function with png_set_read_fn.
Doing this, you can fool png_init_io into thinking that it is reading from a file, while in reality you're reading from a buffer:
struct fake_file
{
unsigned int *buf;
unsigned int size;
unsigned int cur;
};
static ... fake_read(FILE *fp, ...) /* see input and output from doc */
{
struct fake_file *f = (struct fake_file *)fp;
... /* read a chunk and update f->cur */
}
struct fake_file f = { .buf = pngBuff, .size = pngbuffleng, .cur = 0 };
/* override read function with fake_read */
png_init_io(png_ptr, (FILE *)&f);
Try to use png_set_read_fn instead of png_init_io.
Hi fellow stack overflowers,
I'm currently parsing a file which both contains text and binary data. Currently, I'm reading the file in following manner:
QTextStream in(&file);
int index = 0;
while(!in.atEnd()) {
if (index==0) {
QString line = in.readLine(); // parse file here
} else {
QByteArray raw_data(in.readAll().toAscii());
data = new QByteArray(raw_data);
}
index++;
}
where data refers to the binary data I'm looking for. I'm not sure if this is what I want, since the QString is encoded into ascii and I have no idea if some bytes are lost.
I checked the documentation, and it recommends using a QDataStream. How can I combine both approaches, i.e. read lines with an encoding and also read the binary dump, after one line break?
Help is greatly appreciated!
This will do what you want.
QTextStream t(&in);
QString line;
QByteArray raw_data;
if(!in.atEnd()) {line = t.readLine();}
in.reset();
int lineSize = line.toLocal8Bit().size() + 1;
in.seek(lineSize);
if(!in.atEnd())
{
int len = in.size() - lineSize;
QDataStream d(&in);
char *raw = new char[len]();
d.readRawData(raw, len);
raw_data = QByteArray(raw, len);
delete raw;
}
PS: if file format is yours, it will be better to create file with QDataStream and write data with <<, read with >>. This way you can store QByteArray and QString in file without such problems.
I'm trying to write a wchar array to a file in C, however there is some sort of corruption and unrelevant data like variables and paths like this
c.:.\.p.r.o.g.r.a.m. .f.i.l.e.s.\.m.i.c.r.o.s.o.f.t. .v.i.s.u.a.l. .s.t.u.d.i.o. 1.0...0.\.v.c.\.i.n.c.l.u.d.e.\.x.s.t.r.i.n.g..l.i.s.t...i.n.s.e.r.t
are written on to the file along with the correct data (example) I have confirmed that the buffer is null-terminated and contains proper data.
Heres my code:
myfile = fopen("logs.txt","ab+");
fseek(myfile,0,SEEK_END);
long int size = ftell(myfile);
fseek(myfile,0,SEEK_SET);
if (size == 0)
{
wchar_t bom_mark = 0xFFFE;
size_t written = fwrite(&bom_mark,sizeof(wchar_t),1,myfile);
}
// in another func
while (true)
{
[..]
unsigned char Temp[512];
iBytesRcvd = recv(sclient_socket,(char*)&Temp,iSize,NULL);
if(iBytesRcvd > 0 )
{
WCHAR* unicode_recv = (WCHAR*)&Temp;
fwrite(unicode_recv,sizeof(WCHAR),wcslen(unicode_recv),myfile);
fflush(myfile);
}
[..]
}
What could be causing this?
recv() will not null-terminate &Temp, so wcslen() runs over the bytes actually written by recv(). You will get correct results if you just use iBytesReceived as byte count for fwrite() instead of using wcslen() and hoping the data received is correctly null-terminated (wide-NULL-terminated, that is):
fwrite(unicode_recv, 1, iBytesReceived, myfile);