Why does the definition of printf name it __printf - printf

In the printf.c file of the glibc source code package, the function is declared with underscores in the name. Why?
int
__printf (const char *format, ...)

Related

Can't put a space between output and input on the same line

After printing, if I write the name I get:
Insert a name :Andrea
There is no space before Andrea, even if I put the space in the output. How can I add a space before writing the name?
#include <stdio.h>
int main() {
int string[8];
printf("\nInsert a name : ");
printf(" ");
scanf("%s", string);
printf("\nThe name is : %s", string);
return 0;
}
The code that you provided does not compile because the variable string is an array of integers (and not a string as you might think). And when you input the value of it, you're telling the compiler to expect a string ("%s" in scanf("%s", string")).
Change your string declaration to char string[8] and it should work (with the spacing you want):
Note that the value that goes into string will not contain more than 8 characters.
Actually, you did a small mistake in your code, you declared the string to be an array of int & from the code scanf("%s", string") the compiler expects from the user to enter a string as it contains %s as the format specifier. Hence, the code doesn't compile.
In order to correct this, you should declare string as char string[8] (string containing 8 characters).
The correct code is given below :
#include <stdio.h>
int main() {
char string[8];
printf("\nInsert a name : ");
scanf("%s", string);
printf("\nThe name is : %s", string);
return 0;
}
From the above correction your problem for space between input and output will be solved!
Here, is the output which is received from this correction :
I hope so this explanation will be helpful for you!
If any problem persists then feel free to ask in comments! ;-)

Xamarin binding C library params not working (variadic functions)

I need to use a C library and I got it to work on the emulator easily, but on an arm64 device only with some strange trickery. The issue is that C functions with … (variadic functions) do not pass values correctly from C# to the library.
This is the C function, with ...
cmd_ln_t *
cmd_ln_init(cmd_ln_t *inout_cmdln, const arg_t *defn, int32 strict, ...)
{
va_list args;
const char *arg, *val;
char **f_argv;
int32 f_argc;
va_start(args, strict);
f_argc = 0;
while ((arg = va_arg(args, const char *))) {
++f_argc;
E_INFO("name: %s ", arg);
E_INFO(" retrieving value...");
val = va_arg(args, const char*);
E_INFO("value retrieved. \n");
E_INFO("value: %s \n", val);
if (val == NULL) {
E_ERROR("Number of arguments must be even!\n");
return NULL;
}
++f_argc;
}
va_end(args);
.....................................
I check if the values are correct with the E_INFO()
Approach 1 - The default PARAMS doesn't work:
When I use the following default params expression approuch for c bindings, the ‘arg’ printed in the function shows unknown characters and when ‘val’ is used the function crashes.
[DllImport("__Internal")] public static extern unsafe cmd_ln_t*
cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, params string[] arguments);
Approach 2 - a more elaborate approach works:
When I use the a more elaborate approach everything works, on x86_64 architecture normally but for arm64 with a strange work-around.
the binding expression in a more elaborate approach.
[DllImport("__Internal")]
public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2);
[DllImport("__Internal")]
public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2, string arg3);
[DllImport("__Internal")]
public static extern unsafe cmd_ln_t* cmd_ln_init(cmd_ln_t* inout_cmdln, arg_t* defn, int strict, string arg1, string arg2, string arg3, string arg4);
//etc etc… for x numbers of arguments
The binding works works the following code
// works for x86_64
var cmdPointer = MyBindingLib.cmd_ln_init(null, psArgsPointer, 1,
"-hmm", hmmFolder,
"-dict", dictFile,
"-mmap", "no",
"-kws_threshold", "1e-80",
"-lw", "2.0",
null);
// works for arm64
var cmdPointer = MyBindingLib.cmd_ln_init(null, psArgsPointer, 1,
null, null,
null, null, null,
"-hmm", hmmFolder,
"-dict", dictFile,
"-mmap", "no",
"-kws_threshold", "1e-80",
"-lw", "2.0",
null);
As you see, the x86_64 works normally to get the values to the C library.
But the arm64 version needs to have 5 null values, others half of the values won't make it to the C library (I can check that with the E_INFO function in the C function).
Anyone any idea how to get this Xamarin C binding correct with params or without the 5 prefix null values?
Source is on github
uses c library at sphinxbase
It seems to be expected behavior for arm64 architecture, because of the way arm64 functions are invoked.
Invoking functions in a arm64 library that use ...) at the end, you have to take into account that the first 8 argument spots are for 'normal' arguments, then optionally the variable/params can start.
So, in my example I used 5 NULL values to fill the first 8 argument spots, then start the values for the ...)
See full answer:
https://github.com/xamarin/xamarin-macios/issues/10285

C++ Builder Function error [bcc32 - Ambiguity error] inside dll file

I am creating a currency converter Win32 program in Embarcadero C++Builder. I wrote a function for transforming date from format specified on user PC to YYYY-MM-DD format. I need that part because of API settings.
When I have this function inside my project it works fine, but I need to have that function inside a DLL.
This is how my code looks like:
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern DELPHI_PACKAGE void __fastcall DecodeDate(const System::TDateTime DateTime, System::Word &Year, System::Word &Month, System::Word &Day);
extern "C" UnicodeString __declspec (dllexport) __stdcall datum(TDateTime dat) {
Word dan, mjesec, godina;
UnicodeString datum, datum_dan, datum_mjesec, datum_godina;
DecodeDate(dat, godina, mjesec, dan);
if (dan<=9 && mjesec<=9) {
datum_dan="0"+IntToStr(dan);
datum_mjesec="0"+IntToStr(mjesec);
}
if (dan<=9 && mjesec>9) {
datum_dan="0"+IntToStr(dan);
datum_mjesec=IntToStr(mjesec);
}
if (dan>9 && mjesec<=9) {
datum_dan=IntToStr(dan);
datum_mjesec="0"+IntToStr(mjesec);
}
if (dan>9 && mjesec>9) {
datum_dan=IntToStr(dan);
datum_mjesec=IntToStr(mjesec);
}
datum_godina=IntToStr(godina);
return datum_godina+"-"+datum_mjesec+"-"+datum_dan;
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
`
I've included SysUtils.hpp and declared DecodeDate() function, without those lines I have a million errors. But with code looking like this, I am getting this error, which I can't get rid of:
[bcc32 Error] File1.cpp(30): E2015 Ambiguity between '_fastcall System::Sysutils::DecodeDate(const System::TDateTime,unsigned short &,unsigned short &,unsigned short &) at c:\program files (x86)\embarcadero\studio\19.0\include\windows\rtl\System.SysUtils.hpp:3466' and '_fastcall DecodeDate(const System::TDateTime,unsigned short &,unsigned short &,unsigned short &) at File1.cpp:25'
Full parser context
File1.cpp(27): parsing: System::UnicodeString __stdcall datum(System::TDateTime)
Can you help me to get rid of that error?
The error message is self-explanatory. You have two functions with the same name in scope, and the compiler doesn't know which one you want to use on line 30 because the parameters you are passing in satisfy both function declarations.
To fix the error, you can change this line:
DecodeDate(dat, godina, mjesec, dan);
To either this:
System::Sysutils::DecodeDate(dat, godina, mjesec, dan);
Or this:
dat.DecodeDate(&godina, &mjesec, &dan);
However, either way, you should get rid of your extern declaration for DecodeDate(), as it doesn't belong in this code at all. You are not implementing DecodeDate() yourself, you are just using the one provided by the RTL. There is already a declaration for DecodeDate() in SysUtils.hpp, which you are #include'ing in your code. That is all the compiler needs.
Just make sure you are linking to the RTL/VCL libraries to resolve the function during the linker stage after compiling. You should have enabled VCL support when you created the DLL project. If you didn't, recreate your project and enable it.
BTW, there is a MUCH easier way to implement your function logic - instead of manually pulling apart the TDateTime and reconstituting its components, just use the SysUtils::FormatDateTime() function or the TDateTime::FormatString() method instead, eg:
UnicodeString __stdcall datum(TDateTime dat)
{
return FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
}
UnicodeString __stdcall datum(TDateTime dat)
{
return dat.FormatString(_D("yyyy'-'mm'-'dd"));
}
That being said, this code is still wrong, because it is not safe to pass non-POD types, like UnicodeString, over the DLL boundary like you are doing. You need to re-think your DLL function design to use only interop-safe POD types. In this case, change your function to either:
take a wchar_t* as input from the caller, and just fill in the memory block with the desired characters. Let the caller allocate the actual buffer and pass it in to your DLL for populating:
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) int __stdcall datum(double dat, wchar_t *buffer, int buflen)
{
UnicodeString s = FormatDateTime(_D("yyyy'-'mm'-'dd"), dat);
if (!buffer) return s.Length() + 1;
StrLCopy(buffer, s.c_str(), buflen-1);
return StrLen(buffer);
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t buffer[12] = {};
datum(SomeDateValueHere, buffer, 12);
// use buffer as needed...
int len = datum(SomeDateValueHere, NULL, 0);
wchar_t *buffer = new wchar_t[len];
int len = datum(SomeDateValueHere, buffer, len);
// use buffer as needed...
delete[] buffer;
allocate a wchar_t[] buffer to hold the desired characters, and then return a wchar_t* pointer to that buffer to the caller. Then export a second function that the caller can pass the returned wchar_t* back to you so you can free it correctly.
#pragma hdrstop
#pragma argsused
#include <SysUtils.hpp>
extern "C" __declspec(dllexport) wchar_t* __stdcall datum(double dat)
{
UnicodeString s = FormatDateTime("yyyy'-'mm'-'dd", dat);
wchar_t* buffer = new wchar_t[s.Length()+1];
StrLCopy(buffer, s.c_str(), s.Length());
return buffer;
}
extern "C" __declspec(dllexport) void __stdcall free_datum(wchar_t *dat)
{
delete[] dat;
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
wchar_t *buffer = datum(SomeDateValueHere);
// use buffer as needed...
free_datum(buffer);

How to fix error Format specifies type 'char *' but the argument has type 'char'

I get a warning saying:
"Format specifies type 'char *' but the argument has type 'char'" for the student variable. I am copying/pasting the code out of a book into xcode and am not sure how to fix this. The only thing that prints in the console is "(lldb)". Any advice
#include <stdio.h>
void congratulateStudent(char student, char course, int numDays)
{
printf("%s has done as much %s Programming as I could fit into %d days.\n", student, course, numDays);
}
int main(int argc, const char * argv[])
{
// insert code here...
congratulateStudent("mark", "Cocoa", 5);
return 0;
}
void congratulateStudent(char *student, char *course, int numDays)
the %s means that you are going to print a string ( array of chars)
and char student this means that student is a char type
so student here is not a pointer to a string
In order to change the student type from char to a string pointer you have to add asterisk to student char *student
In your code you are calling the congratulateStudent with input parameter string "mark". So to support this string the input parameter student should be defined as pointer of string
so you are missing the asterisk in the definition of student
The same thing for course
void congratulateStudent(char *student, char *course, int numDays)
Use Function signature like because you are passing string as argument to function in main but function has character type argument..

What is a FILE * type in Cocoa,and how properly use it?

I'm trying to run Bash commands from my Cocoa APP. And receive the output. I'm executing all that commands, with Admin Privilege.
How to get output from Admin Priveleges bash script, called from Cocoa?
I guess I need FILE * type to store output, but I don't know how to use it.
What is FILE * type? And how should I use it?
FILE * is a C type and it hasn't got anything to do with Cocoa. It is a handle for an opened file. Here is an example:
#include <stdio.h>
int main () {
FILE *file;
file = fopen("myfile.txt", "w"); // open file
if (!file) { // file couldn't be opened
return 1;
}
fputs("fopen example", file); // write to file
fclose(file);
return 0;
}
In Cocoa, you should normally use NSString's and NSData's writeToURL:atomically:encoding:error: and writeToURL:atomically: methods, respectively.
FILE is an ANSI C structure is used for file handling. fopen function return a file pointer. This pointer, points to a structure that contains information about the file, such as the location of a buffer, the current character position in the buffer, whether the file is being read or written, and whether errors or end of file have occurred. Users don't need to know the details, because the definitions obtained from stdio.h include a structure declaration called FILE. The only declaration needed for a file pointer is exemplified by
FILE *fp;
FILE *fopen(char *name, char *mode);
This says that fp is a pointer to a FILE, and fopen returns a pointer to a FILE. Notice that
FILE is a type name, like int, not a structure tag; it is defined with a typedef.
#include <stdio.h>
int main()
{
FILE * pFile;
char buffer [100];
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else
{
while ( ! feof (pFile) )
{
if ( fgets (buffer , 100 , pFile) != NULL )
fputs (buffer , stdout);
}
fclose (pFile);
}
return 0;
}
This example reads the content of a text file called myfile.txt and sends it to the standard output stream.