I'm interested in unescaping text for example: \ maps to \ in C. Does anyone know of a good library?
As reference the Wikipedia List of XML and HTML Character Entity References.
For another open source reference in C to decoding these HTML entities you can check out the command line utility uni2ascii/ascii2uni. The relevant files are enttbl.{c,h} for entity lookup and putu8.c which down converts from UTF32 to UTF8.
uni2ascii
I wrote my own unescape code; very simplified, but does the job: pn_util.c
Function Description: Convert special HTML entities back to characters.
Need to do some modifications to fit your requirement.
char* HtmlSpecialChars_Decode(char* encodedHtmlSpecialEntities)
{
int encodedLen = 0;
int escapeArrayLen = 0;
static char decodedHtmlSpecialChars[TITLE_SIZE];
char innerHtmlSpecialEntities[MAX_CONFIG_ITEM_SIZE];
/* This mapping table can be extended if necessary. */
static const struct {
const char* encodedEntity;
const char decodedChar;
} entityToChars[] = {
{"<", '<'},
{">", '>'},
{"&", '&'},
{""", '"'},
{"'", '\''},
};
if(strchr(encodedHtmlSpecialEntities, '&') == NULL)
return encodedHtmlSpecialEntities;
memset(decodedHtmlSpecialChars, '\0', TITLE_SIZE);
memset(innerHtmlSpecialEntities, '\0', MAX_CONFIG_ITEM_SIZE);
escapeArrayLen = sizeof(entityToChars) / sizeof(entityToChars[0]);
strcpy(innerHtmlSpecialEntities, encodedHtmlSpecialEntities);
encodedLen = strlen(innerHtmlSpecialEntities);
for(int i = 0; i < encodedLen; i++)
{
if(innerHtmlSpecialEntities[i] == '&')
{
/* Potential encode char. */
char * tempEntities = innerHtmlSpecialEntities + i;
for(int j = 0; j < escapeArrayLen; j++)
{
if(strncmp(tempEntities, entityToChars[j].encodedEntity, strlen(entityToChars[j].encodedEntity)) == 0)
{
int index = 0;
strncat(decodedHtmlSpecialChars, innerHtmlSpecialEntities, i);
index = strlen(decodedHtmlSpecialChars);
decodedHtmlSpecialChars[index] = entityToChars[j].decodedChar;
if(strlen(tempEntities) > strlen(entityToChars[j].encodedEntity))
{
/* Not to the end, continue */
char temp[MAX_CONFIG_ITEM_SIZE] = {'\0'};
strcpy(temp, tempEntities + strlen(entityToChars[j].encodedEntity));
memset(innerHtmlSpecialEntities, '\0', MAX_CONFIG_ITEM_SIZE);
strcpy(innerHtmlSpecialEntities, temp);
encodedLen = strlen(innerHtmlSpecialEntities);
i = -1;
}
else
encodedLen = 0;
break;
}
}
}
}
if(encodedLen != 0)
strcat(decodedHtmlSpecialChars, innerHtmlSpecialEntities);
return decodedHtmlSpecialChars;
}
QString UNESC(const QString &txt) {
QStringList bld;
static QChar AMP = '&', SCL = ';';
static QMap<QString, QString> dec = {
{"<", "<"}, {">", ">"}
, {"&", "&"}, {""", R"(")"}, {"'", "'"} };
if(!txt.contains(AMP)) { return txt; }
int bgn = 0, pos = 0;
while((pos = txt.indexOf(AMP, pos)) != -1) {
int end = txt.indexOf(SCL, pos)+1;
QString val = dec[txt.mid(pos, end - pos)];
bld << txt.mid(bgn, pos - bgn);
if(val.isEmpty()) {
end = txt.indexOf(AMP, pos+1);
bld << txt.mid(pos, end - pos);
} else {
bld << val;
}// else // if(val.isEmpty())
bgn = end; pos = end;
}// while((pos = txt.indexOf(AMP, pos)) != -1)
return bld.join(QString());
}// UNESC
Related
So i have to create two set of coordinates depending on whether the latitude or longitude are even or odd. But this two errors wont let me read and save them correctly, and i have 0 clue on what to do.
This is the part of the code where i create that function.
So where it says numeros[j++]=datos[i++] is where the error is.
The locations are in a file saved like this:
37.3124631552;93.0636996608
20.4690509824;64.2966293504
25.230157824;13.5498533888
int CrearConjuntos (char NombreFichero[], char datos[MaxDatos][MaxCaracter], tConjunto *conjuntoUno, tConjunto *conjuntoDos)
{
int nComas=0, nComass=0;
char numeros[1000];
int aux,aux2;
int i, longitud[MaxDatos], num, a = 0, b = 0, c = 0,j;
FILE *pFich = fopen (NombreFichero, "r");
printf ("\n LEER FICHERO");
if (pFich == NULL)
{
printf ("\n\n Error: No se puede abrir el fichero \"%s\" ", NombreFichero);
}
else
{ for (i=0; i<MaxDatos; i++)
{
fgets (datos[i], MaxCaracter, pFich);
while(nComas<1){
if(datos[i]==';') nComas++;
numeros[j++] = datos[i++];
if(datos[i]=='.'){
numeros[j]= '\0';
aux=atoi(numeros);
}
}
if (aux%2==0)
{
num = i;
if (a == 0)
{
initCjto (conjuntoUno, num);
}
else
{
introducir (conjuntoUno, num);
}
a++;
}
}
for (i=0; i<MaxDatos; i++){
fgets (datos[i], MaxCaracter, pFich);
while(nComass<1){
if(datos[i]==';') nComass++;
i++;
}
i++, j=0;
while(datos[i]!='\0'){
numeros[j++] = datos[i++];
if(datos[i]=='.'){
numeros[j]= '\0';
aux2=atoi(numeros);
}
}
if (aux%2==1)
{
num = i;
if (b == 0)
{
initCjto (conjuntoDos, num);
}
else
{
introducir (conjuntoDos, num);
}
b++;
}
}
fclose(pFich);
return 1;
}
}
I met a weird question.I have been using FFmpeg's NVENC to encode video .It is strange that I can use h264_nvenc smoothly without problem,but when I replace h264_nvenc with hevc_nvenc,I got the problem "No NVENC capable devices found".The FFmpeg version I am using is 3.2,and I use command line to encode with hevc_nvenc,it works ok.My code is here:
#include "stdafx.h"
int flush_encoder(AVFormatContext *fmt_ctx, unsigned int stream_index)
{
int ret;
int got_frame;
AVPacket enc_pkt;
if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &
CODEC_CAP_DELAY))
return 0;
while (1) {
printf("Flushing stream #%u encoder\n", stream_index);
//ret = encode_write_frame(NULL, stream_index, &got_frame);
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = avcodec_encode_video2(fmt_ctx->streams[stream_index]->codec, &enc_pkt,
NULL, &got_frame);
av_frame_free(NULL);
if (ret < 0)
break;
if (!got_frame){
ret = 0;
break;
}
printf("Succeed to encode 1 frame! 编码成功1帧!\n");
/* mux encoded frame */
ret = av_write_frame(fmt_ctx, &enc_pkt);
if (ret < 0)
break;
}
return ret;
}
int main(int argc, char* argv[])
{
AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* video_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
uint8_t* picture_buf;
AVFrame* picture;
int size;
FILE *in_file = fopen("test_yuv420p_320x180.yuv", "rb"); //Input YUV data 视频YUV源文件
int in_w = 320, in_h = 180;//宽高
int framenum = 100;
const char* out_file = "ds.hevc";
av_register_all();
//Method1 方法1.组合使用几个函数
pFormatCtx = avformat_alloc_context();
//Guess Format 猜格式
fmt = av_guess_format(NULL, out_file, NULL);
pFormatCtx->oformat = fmt;
//Method 2 方法2.更加自动化一些
//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
//fmt = pFormatCtx->oformat;
//Output Format 注意输出路径
if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0)
{
printf("Failed to open output file! 输出文件打开失败");
return -1;
}
video_st = avformat_new_stream(pFormatCtx, 0);
video_st->time_base.num = 1;
video_st->time_base.den = 25;
if (video_st == NULL)
{
return -1;
}
//Param that must set
pCodecCtx = video_st->codec;
pCodecCtx->codec_id =AV_CODEC_ID_HEVC;
//pCodecCtx->codec_id = fmt->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
pCodecCtx->width = in_w;
pCodecCtx->height = in_h;
pCodecCtx->time_base.num = 1;
pCodecCtx->time_base.den = 25;
pCodecCtx->bit_rate = 400000;
pCodecCtx->gop_size = 12;
//H264
//pCodecCtx->me_range = 16;
//pCodecCtx->max_qdiff = 4;
//pCodecCtx->qcompress = 0.6;
pCodecCtx->qmin = 10;
pCodecCtx->qmax = 51;
//Optional Param
pCodecCtx->max_b_frames = 3;
// Set Option
AVDictionary *param = 0;
//H.264
if (pCodecCtx->codec_id == AV_CODEC_ID_H264) {
av_dict_set(¶m, "preset", "slow", 0);
av_dict_set(¶m, "tune", "zerolatency", 0);
}
//H.265
if (pCodecCtx->codec_id == AV_CODEC_ID_H265){
av_dict_set(¶m, "x265-params", "qp=20", 0);
av_dict_set(¶m, "preset", "default", 0);
av_dict_set(¶m, "tune", "zero-latency", 0);
}
//Dump Information 输出格式信息
av_dump_format(pFormatCtx, 0, out_file, 1);
//pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
pCodec = avcodec_find_encoder_by_name("hevc_nvenc");
if (!pCodec){
printf("Can not find encoder! 没有找到合适的编码器!\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, ¶m) < 0){
printf("Failed to open encoder! 编码器打开失败!\n");
return -1;
}
picture = av_frame_alloc();
size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
picture_buf = (uint8_t *)av_malloc(size);
avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
//Write File Header 写文件头
avformat_write_header(pFormatCtx, NULL);
AVPacket pkt;
int y_size = pCodecCtx->width * pCodecCtx->height;
av_new_packet(&pkt, y_size * 3);
for (int i = 0; i<framenum; i++){
//Read YUV 读入YUV
if (fread(picture_buf, 1, y_size * 3 / 2, in_file) < 0){
printf("Failed to read YUV data! 文件读取错误\n");
return -1;
}
else if (feof(in_file)){
break;
}
picture->data[0] = picture_buf; // 亮度Y
picture->data[1] = picture_buf + y_size; // U
picture->data[2] = picture_buf + y_size * 5 / 4; // V
//PTS
picture->pts = i;
picture->format = pCodecCtx->pix_fmt;
picture->width = in_w;
picture->height = in_h;
int got_picture = 0;
//Encode 编码
int ret = avcodec_encode_video2(pCodecCtx, &pkt, picture, &got_picture);
if (ret < 0){
printf("Failed to encode! 编码错误!\n");
return -1;
}
if (got_picture == 1){
printf("Succeed to encode 1 frame! 编码成功1帧!\n");
pkt.stream_index = video_st->index;
ret = av_write_frame(pFormatCtx, &pkt);
av_free_packet(&pkt);
}
}
//Flush Encoder
int ret = flush_encoder(pFormatCtx, 0);
if (ret < 0) {
printf("Flushing encoder failed\n");
return -1;
}
//Write file trailer 写文件尾
av_write_trailer(pFormatCtx);
//Clean 清理
if (video_st){
avcodec_close(video_st->codec);
av_free(picture);
av_free(picture_buf);
}
avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx);
fclose(in_file);
system("pause");
return 0;
}
Help!!!!
after a few days of strugglling,once again I try anwser the question myself.The key point is ,when encoding with hevc_nvenc,you must set pCodecCtx->max_b_frames = 0;(at least for version 3.2 of ffmpeg).
I'm currently working on a server which is part of my course requirement. The specs require me to parse a request line and store the appropriate data as absolute path (abs_path) and query.
Here is my code:
bool parse(const char* line, char* abs_path, char* query)
{
int space = 0;
if (strchr(line, '"') != NULL)
{
error(400);
return false;
}
for (int i = 0; line[i] != '\0'; i++)
{
if (line[i] == ' ')
{
space++;
}
}
if (space != 2)
{
error(400);
return false;
}
if (strncmp("GET ", line, 4) != 0)
{
error(405);
return false;
}
line = strchr(line, ' ');
line++;
if (strncmp("/", line, 1) != 0)
{
error(501);
return false;
}
int j = 0;
int k = 4;
while (line[k] != ' ')
{
int m = k;
abs_path[j] = line[k];
j++;
if (line[k+1] == '?')
{
abs_path[j] = '\0';
int l = 0;
m = k+2;
while (line[m] != ' ')
{
query[l] = line[m];
l++;
m++;
}
if (line[m] == ' ' && l == 0)
{
query[0] = '\0';
}
}
k = m;
k++;
if (line[k] == ' ')
{
abs_path[j] = '\0';
break;
}
}
char* last = strrchr(line, ' ');
last++;
if (strcmp("HTTP/1.1", last) != 0)
{
error(505);
return false;
}
free(abs_path);
return true;
}
I keep getting a segmentation fault with this. After some debugging, I've found the segmentation fault to be eliminated if I declare, on line 20, abs_path as an array instead of a pointer. However, it is necessary for me to declare abs_path as a pointer, so I need another solution to this. Can someone explain to me what exactly I am doing wrong with regards to strings and their handling?
I have been quite rusty with this due to personal reasons so pardon me if I misunderstand something basic.
Thank you in advance!
You need to allocate memory for the char*. An array does this automatically during compile time. Try malloc.
char* abs_path = 0;
abs_path = (char*)malloc(256);
Essentially, malloc performs an operating system call to reserve sequential memory from the heap. The argument of malloc is how many bytes to reserve. Therefore, you should be aware that the example above enables the abs_path char* to point to a string that is at max 255 characters (leaving 1 byte for the null character '\0'). Don't let your code write more than 255 characters or you will overwrite other data in memory, which is why you received a seg-fault before.
As someone else noted, you should DEFINITELY free up memory reserved dynamically with malloc.
free(abs_path);
I have written a non recursive solution to the Ackermann function, it seems to work perfectly and work faster than the common recursive solution. So I am confused as to why it is a non primitive recursive function if it can be solved iteratively? Could anyone tell me if I have misunderstood something about what primitive recursive functions are or who should I talk to about this to get an answer?
Below is the Java code:
import java.util.Scanner;
import java.util.ArrayList;
public class ackermann {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Enter m:");
int m = in.nextInt();
System.out.println("Enter n:");
int n = in.nextInt();
ack(m, n);
}
public static void ack(int inM, int inN){
if(inM < 0 || inN < 0) return;
ArrayList<ArrayList<Integer>> arr = new ArrayList<ArrayList<Integer>>();
for(int m = 0; m <= inM; m++){
arr.add(new ArrayList<Integer>());
}
Boolean done = false;
while(done == false){
for(int m = 0; m <= inM; m++){
int n = arr.get(m).size();
int a = 0;
if(m == 0) a = n + 1;
else if(n == 0){
if(arr.get(m - 1).size() <= 1) break;
a = arr.get(m - 1).get(1);
} else {
int k = arr.get(m).get(n - 1);
if(arr.get(m - 1).size() <= k) break;
a = arr.get(m - 1).get(k);
}
arr.get(m).add(a);
if(m == inM && n == inN){
System.out.println("Ack(" + inM + ", " + inN + ") = " + a);
done = true;
break;
}
}
}
}
}
Primitive recursive functions can be implemented using only assignment, +, and definite loops. By this I mean loops of the form:
for(int i = 0; i < n; i++) { ... }
Where n is a variable that isn't changed in the loop body. To get Ackermann's function, which majorizes all primitive recursive functions, one needs to add either a goto command or indefinite loops like your while loop.
I am building a windows phone app and i added a windows phone runtime component with this function in order to decode a string which i provide. The same function seems to be working correctly in a console application if i provide an std::string and return the same type. I think my problem is that i am converting from one type to another in the wrong way, but i can't see what i am doing wrong!
String^ Base64Encoding::base64_decode(String^ someString) {
std::wstring ws1(someString->Data());
std::string encoded_string(ws1.begin(), ws1.end());
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
std::wstring widestr = std::wstring(ret.begin(), ret.end());
const wchar_t* wcstring2 = widestr.c_str();
return ref new String(wcstring2);
}
So what am i doing wrong here?
Normally, the output of a Base64 decode isn't a string, it's a byte array. Base64 can encode arbitrary binary data, and depending on the string's encoding, not all byte arrays are valid strings.
To do a Base64 decode, use Convert::FromBase64String. If you want to interpret that byte array as a string, I suggest you use one of the Encoding classes, such as Encoding.Unicode, to do that conversion.