#include <cini.h>
int main() {
int a ;
a = 21 ;
printf(a);
return 0;
}
Questions :
1) on the toolbar, once I've written the code, the "execute" or "compile" functions on Geany (a C compiler) seem to be disabled
2) what's wrong with my code ?
I'm about to learn C, so please be nice with a rookie.
Geany is an editor, not a compiler. If the compile and execute functions are disabled it could be because it is unable to find your actual compiler (make sure you have one installed), or because you haven't saved your file as C code.
The first argument to printf must be the format string. If you want to print an integer as decimal, you need to use the %d conversion specifier, like this:
printf("%d\n", a);
The \n after the %d prints the linefeed character to the output. You can read about the printf function here.
You need to include at least stdio.h, because printf is declared in that header. The only reference I could find to cini.h was this header here which won't work in a C program because it is C++ code.
Related
While working on an embedded project, I noticed that sprintf() method for the following code:
char ln2[16];
sprintf(ln2, "%f Volt", Data[Position].Voltage1);
generates the question mark character as output.
The output generated from the code above is:
? Volt
while the input is declared as double Voltage1 = 0.0;
The same issue does not seem to apply while trying to format an integer.
The following works as expected:
char ln1[16];
sprintf(ln1, "POSITION %d", (Position + 1));
and outputs POSITION 3 where the Position is a global variable and declared as int.
The structure that actually holds the data is:
struct data
{
int Position;
double Voltage1;
double Voltage2;
};
All above while using the C/C++
and the Platform.io extensions both for VS Code.
What is going on wrong here?
Embedded versions of the printf usually do not implement float number handling. You need to let the linker to link the correct version of the function. For example for ARM gcc it will be -u _printf_float or/and -u _scanf_float
ln2 points to a string literal. String literals are read-only, so when you attempt to write to it you invoke undefined behavior.
You should instead define ln2 as a character array which is writable.
char ln2[16];
I'm learning C. So I wrote this distance timer program.
It runs well with gnu-gcc compiler.
But but with gnu-gcc for avr it does compile but when I run it I get only a cmd session that does nothing except disappearing once I press any button.
I want to know why.
I am using code blocks and here is my code
#include<stdio.h>
#include<stdlib.h>
#define speedpersecond 5
int main()
{
char time [5];
double distance;
printf("Please enter time in seconds");
gets(time);
distance = atoi(time) * speedpersecond;
printf("Distance is %g ", distance);
return 8585;
}
You are probably running into the reason gets have been deprecated since the C99 standard, and removed completely in the C11 standard: Buffer overflows are way to easy.
If you give more than four characters as input then gets will write out of bounds of the array and you will have undefined behavior.
Instead use fgets to read lines in a safe way.
And regarding that return from the main function. Many systems (including all POSIX systems, like macOS and Linux) uses eight bits for the return value. Also, anything but zero is considered to be a failure by shells and calling environments.
You should also know that the atoi function have no major error checking. It's impossible to know if the string you pass contains e.g. "0" or don't have any digits at all. In both cases it will return 0. A safer function which will help you detect errors is the strtol function.
The result of this code down below should be 30, however when compiled and run this is giving me the following result
the result of 2358968 and 0 is 4200271, a , b , result
I
don't understand when I have no variables of that value how could the result be like that?
#include<stdio.h>
#include<conio.h>
void add( int , int );
int main(){
add(10,20);
getch();
return 0 ;
}
void add(int a, int b){
int result = a + b;
printf("the result of the %d and %d is %d, a, b, result");
}
In your code,
printf("the result of the %d and %d is %d, a, b, result");
should be
printf("the result of the %d and %d is %d\n", a, b, result);
^
|
//format string ends here
// arguments for format specifiers are meant to be
// supplied as different arguments to `printf()`, not as a part of <format> string itself
From the man page of printf()
int printf(const char *format, ...);
and
The functions in the printf() family produce output according to a format ....
So basically your code should be
printf("<format>", var1, var2,....);
The supplied variables are not part of the format.
The problem in your code were missing variables (arguments) for supplied format specifiers. As per the C11 standard , chapter 7.21.6.1, paragraph 2
[...] If there are insufficient arguments for the format, the behavior is
undefined. [...]
So, your code produces undefined behaviour printning out some junk value.
Moral of the Story : If you had enabled compiler warnings, you compiler should warn you about missing (mismatch) agruments in printf(). So, always enable warnings.
You have closed the " at the end of the line. and in the printf function you have specified the %d So the %d will not have the variable to point and fetch the value.
You will get the warning message that %d expects a matching int
It will have the garbage value in that position, So it is printing some value.
Sourav Ghosh answered to most of your questions; he rightly suggested to enable all warnings when compiling. If your compiler is (notably on Linux) some recent GCC or Clang/LLVM pass -Wall -Wextra -g to the gcc or clang command (to get nearly all warnings, some extra ones, and debug information). Others compiler options (-fsanitize=address etc etc...) and other tools (the gdb debugger, the valgrind tool, strace, ...) might be useful too!
I dont understand when I have no variables of that value how could the
result be like that?
Because you have encountered undefined behavior. Read much more about it (in particular Lattner's blog on What Every C Programmer should know about Undefined Behavior), and work hard to always avoid it in all cases. Be aware that with UB, your (or any other) program might seems to work while in fact it has some undefined behavior.
The particular garbage (or apparently random) values that are printed : might not be reproducible, and can be explained only by diving into every implementation details, including looking into the machine code generated by your particular compiler and inspecting some machine state (register values); concretely the printf implementation on your system is probably using some stdarg(3) things and fetching some values from uninitialized memory or register which happens to have some previous "garbage" value (at the machine level).
See also this answer (and many others) about undefined behavior. Work hard to always avoid it.
Remember that when coding (even in C) you are ultimately coding for some virtual or abstract machine which is not the real computer. Even if writing all the software levels from the operating system kernel included - that would take you many dozens of years at least -, you are coding for some specified abstraction and you have to ignore some misbehavior of your computer (e.g. if it breaks, get some cosmic rays, etc etc...) outside of these abstractions. The C99 or C11 programming language standard specification (a technical document of several hundred pages in English), with the POSIX 2008 operating system specification, are useful abstractions to code software for.
printf statement is the reason for undesired output,
printf("the result of the %d and %d is %d, a, b, result");
There is no arguments specified for format specifier, the position of " has to be changed.
the statement should be like this
printf("the result of the %d and %d is %d", a, b, result);
In your printf statement it was taking garbage value since no arguments were specified there for %d.
printf("the result of the %d and %d is %d, a, b, result");
it has to be
printf("the result of the %d and %d is %d", a, b, result);
it will read and assign the %d value from left to write.
printf returns number of characters
i am learning now c and i come up with this example, where i can print a text using pointers.
#include <stdio.h>
main ()
{
char *quotes = "One good thing about music, when it hits you, you feel no pain. \"Bob Marley\"\n";
printf(quotes);
}
I get a warning from the compiler "format not a string literal and no format arguments" and when I execute the program it runs successfully.I read some other questions here that they had the same warning from the compiler but I didn't find an answer that fits me. I understood the reason why i get this message:
This warning is gcc's way of telling you that it cannot verify the format string argument to the printf style function (printf, fprintf... etc). This warning is generated when the compiler can't manually peek into the string and ensure that everything will go as you intend during runtime...
Case 3. Now this is somewhat your case. You are taking a string generated at runtime and trying to print it. The warning you are getting is the compiler warning you that there could be a format specifier in the string. Say for eg "bad%sdata". In this case, the runtime will try to access a non-existent argument to match the %s. Even worse, this could be a user trying to exploit your program (causing it to read data that is not safe to read).
(See the answer)
but what i have to add in my case to in order to have not warnings from the compiler?
Change it to printf("%s", quotes); which adds the specifier that quotes is a 'string', or array of char.
You need to tell printf what is it that you are printing. %s descriptor will tell printf that you are printing a string.
Format of printf = ("descriptor of what type of data you are printing",variable holding the data);
descriptor for strings is %s, for characters %c, for int %d
Change printf to:
printf("%s",quotes);
You have to specify format string - in simplest form:
char *quotes = "One good thing about music(...)\n";
printf("%s", quotes);
or, you can use format string to decorate output:
char *quotes = "One good thing about music(...)"; // no newline
printf("%s\n", quotes); // newline added here
or, if you don't want to mess with format strings:
char *quotes = "One good thing about music(...)"; // no newline
puts(quotes); // puts() adds newline
or
char *quotes = "One good thing about music(...)\n";
fputs(quotes,stdout);
This warning is gcc's way of telling you that it cannot verify the format string argument to the printf style function (printf, fprintf... etc). This warning is generated when the compiler can't manually peek into the string and ensure that everything will go as you intend during runtime. Lets look at a couple of examples.
So as other suggested explicitly use format specifier to tell the compiler...i.e.
printf("%s",quotes);
You are getting the warning because it is dangerous when the string you are printing contains '%'. In this line it makes no sense for percents but when you want to print this for instance:
int main ()
{
int percent = 10;
char *s = "%discount: %d\n";
printf(s, percent);
return 0;
}
your program will likely crash when printf encounters the second percent and it tries to pop a value from the stack from printf.
When you want to print a percent sign use: "%%discount:"
Try this:
#include <stdio.h>
main ()
{
char *quotes = "One good thing about music, when it hits you, you feel no pain. \"Bob Marley\"\n";
puts(quotes); //Either
printf("%s",quotes);//or
return 0;
}
I searched around a little bit for information on this but didn't find anything satisfactory. Is there some special behavior to the function call
sprintf(someString, "");
that explains why this is warning (on gcc with -Wall)? I only managed to find that the C standard allows zero-length format strings.
I tried the following example
#include <stdio.h>
int main()
{
char str[2] = {'a', 'a'};
sprintf(str, "");
printf("\'%c\'\'%c\'\n", str[0], str[1]);
return 0;
}
which prints out
'''a'
which is exactly what I expected to see.
So, why the warning?
The fact that GCC issues a warning usually has nothing to do with whether the construct is legal C, but whether the GCC developers consider it either a likely indication that you meant something other than what you write, or just bad style. Here are some examples:
if (x = 0) — you almost surely meant if (x == 0).
printf(str) — you almost surely meant either fputs(str, stdout) or printf("%s", str); as written, the code is very dangerous.
if (foo == bar & MASK) — you almost surely meant if (foo == (bar & MASK)).
etc.
In your case, I think GCC is questioning why you're calling sprintf(String, "") to do the equivalent of String[0]=0; (the latter is much shorter, faster, and clearer).
You're getting the warning because gcc knows that the second argument to sprintf() should be a non-empty string, typically one with various format specifications — a functionally equivalent and "more legal" call to the one you're doing in your code would be sprintf(str, "%s", ""). Also, there's almost always one to N additional arguments, enough to fulfill the format specifications. As you're using it here, you're using it as a kind of strcpy(), which, while technically valid, is a very odd way to use the standard library.
It's simply a warning by GCC. If you wish to suppress it for one part of your application, you can do the following:
#pragma GCC diagnostic ignored "-Wformat-zero-length"
int main()
{
// code that produces a warning
}
#pragma GCC diagnostic warning "-Wformat-zero-length"