|
I've been tasked with updating a function which currently reads in a configuration file from disk and populates a structure:
static int LoadFromFile(FILE *Stream, ConfigStructure *cs)
{
int tempInt;
...
if ( fscanf( Stream, "Version: %d\n",&tempInt) != 1 )
{
printf("Unable to read version number\n");
return 0;
}
cs->Version = tempInt;
...
}
to one which allows us to bypass writing the configuration to disk and instead pass it directly in memory, roughly equivalent to this:
static int LoadFromString(char *Stream, ConfigStructure *cs)
A couple of things to note:
• The current LoadFromFile function is incredibly dense and complex, reading dozens of versions of the config file in a backward-compatible manner, which makes duplication of the overall logic quite a pain.
• The functions that generate the config file and those that read it originate in totally different parts of the old system and therefore don't share any data structures so I can't pass those directly. I could potentially write a wrapper, but again, it would need to handle any structure passed in a backward-compatible manner.
• I'm tempted to just pass the file as is in as a string (as in the prototype above) and convert all the fscanf's to sscanf's but then I have to handle incrementing the pointer along (and potentially dealing with buffer overrun errors) manually.
• This has to remain in C, so no C++ functionality like streams can help here
Am I missing a superior choice? Is there a good method for making a FILE * that simply focuses to an area in memory rather than on a disk? Any pointers, ideas or other assistance is enormously valuable.
|
|
|
|
|
|
Your LoadFromString method could write the string to a temporary file, open the file for input and pass the FILE* to LoadFromFile . That way you would not require any changes to the existing code.
|
|
|
|
|
sahil Ranka wrote: Is there a good method for making a FILE * that simply focuses to an area in memory rather than on a disk? Is mmap() of any value here?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
I need to do the following request within a C++ app (response is json):
curl --header "x-api-key:ABCD" -s https:
1. Can I replace curl with another protocol ? (This is not mandatory, could be as it is now)
2. Is there a header only c++ lib that can complete this request ? Of course, I know there is REST SDK library, but it is too much trouble for that simple request.
Thank you.
modified 4-Jul-22 10:07am.
|
|
|
|
|
curl isn't a protocol, as such, but a CLI tool for data transfer using urls. The underpinnings are based on libcurl, a C library, that implements the data trasfer. As such, you can make API calls directly from your C++ program. Another option would be to look into popen() e.g.
#include <cstdio>
int main()
{
FILE *pipe = popen("curl --header \"x-api-key:ABCD\" -s https://api.test.se/api/mydata", "r");
while( {
}
fclose(pipe);
}
Keep Calm and Carry On
|
|
|
|
|
Hmm ... I tried:
FILE* pipe = _popen("curl --header \"x-api-key:ABCD\" -s https://api.test.se/api/mydata", "r");
while (true)
{
pipe->_Placeholder;
break;
}
fclose(pipe);
but I cannot retrieved any data from pipe ...
|
|
|
|
|
using a C style FILE * you have to use C stdio functions. So for example you could do
#include <stdio>
#include <cstdlib>
FILE *pipe = popen( ... );
char *buff = NULL;
size_t blen = 0;
while( getline(&buff, &blen, pipe) > 0) {
}
free(buff);
I generally prefer getline() to fgets() when using cstdio because it allocates and grows the input buffer as needed.
If you wish to stick with a more C++ style interface, then maybe look into Boost.Process
I think you've mentioned QT as part of your framework, so there's QProcess as well.
Keep Calm and Carry On
|
|
|
|
|
The C++ app is MFC app ...
|
|
|
|
|
For some reason, I was assuming you were using linux. If you're on windows, there's no getline in the C stdio library, so you'll have to use fgets() or another C stdio FILE i/o function.
It might be a better choice to use the libcurl API directly. Or another C/C++ client library. A quick google search turned up Windows HTTP Services - Win32 apps | Microsoft Docs , but that appears to be a Win32 API, so may not be applicable to your situation. There's also GitHub - embeddedmz/httpclient-cpp: C++ client for making simple HTTP requests which might work for you too. I have not tried this package, so cannot speak to its quality or suitability for any purpose, what so ever. Caveat usor.
Keep Calm and Carry On
|
|
|
|
|
|
std::getline() isn't part of C stdio, its part of C++. The getline with the signature int getline(char **, size_t *, FILE *) (i.e C stdio, thus the FILE * parameter) is not provided by MS in the windows C/C++ environment. Or at least it wasn't with VS 2017. It might have been added since then, but I don't think so.
Keep Calm and Carry On
|
|
|
|
|
I have tried:
std::ifstream ifs("curl --header \"x-api-key:ABCD\" -s https://api.test.se/api/mydata");
while (ifs.good())
{
std::string line;
while (std::getline(ifs, line))
{
std::cout << line.c_str() << std::endl;
}
}
Nothing retrieved.
|
|
|
|
|
std::ifstream reads files, and does not have a constructor which executes an external program. You should go back to pure C and use the _popen function.
[edit]
This all you need:
char buffer[132];
FILE* pipette = _popen("curl --header \"x-api-key:ABCD\" -s https://api.test.se/api/mydata", "r");
while (fgets(buffer, 132, pipette))
{
printf("%s", buffer);
}
[/edit]
modified 4-Jul-22 15:32pm.
|
|
|
|
|
Yes, that seems to work. Thank you all of you !
|
|
|
|
|
Of course not, unless you actually have a file in your current directory called curl --header "x-api-key:ABCD" -s https://api.test.se/api/mydata.
Keep Calm and Carry On
|
|
|
|
|
I tried to do a basic calculation for testing the performance of different programming languages:
C/C++: (***3.05 s***)
int main()
{
int start = clock();
double result;
for (size_t i = 1; i < 100000000; i++)
{
result = sin((i * 25) / i * i);
}
int end = clock();
std::cout << "it took " << end - start << "ticks std::endl;
}
C#: (***2.452 s***)
using System.Diagnostics;
class TestClass
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
double result;
sw.Start();
{
for (int i = 1; i < 100000000; i++)
{
result = Math.Sin((i * 25)/i * i);
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString());
}
}
And the same calculation in Python took 22.14 s to complete
Why is C# faster than C++?
|
|
|
|
|
I'd expect all "intermediate" calculations in C# to be performed as "int", since you have not supplied a single float or double on the right of the equation.
And you neglected to display / verify "result".
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Note that Math.Sin is implemented in native code, see the Reference Source (not for the implementation, but for the fact that there's no implementation there). So this isn't really a benchmark of C# vs C++, but one sine written in C++ vs another sine written in C++.
|
|
|
|
|
Both of the previous answers are correct.
On my machine, with VS2019, this code
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
double result=0.0;
sw.Start();
{
for (int i = 1; i < 100000000; i++)
{
result += Math.Sin((i * 25.0) / i * i);
}
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString());
Console.WriteLine(string.Format("{0}",result));
} produces
4739
-7,98150964297362
While the following
int main()
{
int start = clock();
double result = 0.0;
for (size_t i = 1; i < 100000000; i++)
{
result += sin((i * 25.0) / i * i);
}
int end = clock(); std::cout << (1000.0 * (end - start) / CLOCKS_PER_SEC) << "\n";
std::cout << result << "\n";
} outputs
4153
-7.98151
"In testa che avete, Signor di Ceprano?"
-- Rigoletto
|
|
|
|
|
how to create
image background datagrid
|
|
|
|
|
|
Anything not in the foreground, is considered as being in the background.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
could you guys recommend me a file IO library. I need not just the library itself but also some explanations to it, like an article.
|
|
|
|
|
Not sure what you're looking for. C and C++ have file I/O.
For C++, start here[^]. Directory-level stuff was added in C++17 as <filesystem>[^].
For C, look here[^].
|
|
|
|