#include "stdio.h"
#include "conio.h"
int main(void)
{
if(printf("ABC"))
{
}
else
{
printf("XYZ");
}
_getch();
return 0;
}
output : ABC
----------------------------------------------------------------------------------------
#include "stdio.h"
#include "conio.h"
int main(void)
{
if(puts("ABC"))
{
}
else
{
printf("XYZ");
}
_getch();
return 0;
}
output : ABC XYZ
(IDE : MSVC++)
what is the difference between printf and puts in if statement in above 2 programs??
printf returns the number of character written
puts returns a non-negative value in case of success
As a result :
In the first code, printf returns a positive value which evaluates to true, the else branch is never executed, thus printing ABC only
In the second code, puts most likely succeeds and returns 0 which evaluates to false, the else branch gets executed, thus printing both ABC and XYZ
As pointed out by others, puts will also append a newline while printf won't.
puts() appends a newline and returns a different value (non-negative [which could include 0] on success, -1 on failure).
printf returns the number of characters printed (so when successfully printing a non-empty strong, the return value is not 0 and thus true in a boolean context), while puts simply returns a non-negative number to indicate success (which might very well be 0 aka false).
printf on success returns the number of characters written which in your case is 3.
puts on success returns a non-negative number which could also be 0. Looks like it returned a 0 in your case making the else part to execute.
Related
why I get the result n as the length of first string
// Example program
#include <iostream>
#include <string>
int main()
{
int n = printf("jjj");
printf("%d",n); // jjj3
return 0;
}
thanks a lot
printf returns the number of characaters that have been written, as stated in its manual (printf(3))
Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output to strings).
Hence the 3 in your output. The jjj printed string comes from the first printf call.
int n = printf("jjj"); // prints "jjj"
printf("%d", n); // prints "3" (assuming previous printf did not fail)
printf also return the number of char
Is there a way how to check if some specific characters were given on input using scanf without using character conversions?
int main(void)
{
if(scanf("{ ["))
printf("GOOD INPUT\n");
else
printf("BAD INPUT\n");
return 0;
}
This code always gives the bad input option (it expects scanf return value to be 1) but interestingly if I enter other than the desired characters it gives the bad input imediately but if I enter it as its specified in the scanf it blows the bad input at me AFTER I enter the whole input.
So it must be awaiting the input to be in that specified format but my question is: How can I check it, without any conversions, and make according action depending on wether the input was entered correctly or not?
You might use the %n conversion of scanf (it sets below into pos the number of characters read so far)
int pos= -1;
if (scanf("{ [%n", &pos) >=0 && pos>0)
printf("GOOD INPUT\n");
else
printf("BAD INPUT");
Beware, the return count of scanf might be implementation specific (it probably stays at 0). But pos get assigned to a positive offset of scanf did get { followed by some (zero or more) space-like characters followed by a [.
However, what you probably want is some lexical analysis and parsing, then scanf is not a good solution. You'll better read the entire line (e.g. with fgets or getline) and parse it later.
See also the man page of scanf(3)
scanf (and cousins) returns a count of the number of successful conversions. If you specify 0 conversions, then its return value will always be 0.
To use scanf for this task, I'd probably use a couple of scanset conversions:
char a[2], b[2];
if (scanf("%1[{] %1[[]", &a, &b) == 2)
printf("Matched");
Or, you could simplify this a little bit:
char a[2];
if (scanf("{ %1[[]", &a) == 1)
Either way, we've specified each scan set to match only one specified character, but it's still a conversion, so we can see whether it succeeded or failed.
Unfortunately, we still have to assign the result somewhere. scanf does support using * like this: "%*s", to tell it to read a string, but not store the result anywhere--but when you do so, that conversion doesn't get counted in the return value, so (much like before) we can't use it to determine whether we got a match or not.
If good input needs to exactly 3 characters: { space [, use "%*1[ ]" to scan a space and "%n", which saves the scan character count, to insure scanning reach the expected end.
int main(void) {
int n = -1;
scanf("{%*1[ ][%n", *n);
if (n >= 0) {
printf("GOOD INPUT\n");
} else {
printf("BAD INPUT\n");
}
return 0;
}
I'd recommend to read a line of input with fgets() first and then parse the buffer. That can leave stdin in a better known state when bad input happens.
I recently tried to use fgets() instead of scanf() to read a string for code security reasons. I used a simple function that I found here to check for errors (no input and too long input). The problem is that whenever i press "ENTER" without actually writing anything, fgets() doesn't return NULL and my program is not able to show the NO_INPUT error.
Here's main.cpp:
#include <stdlib.h>
#include <stdio.h>
#include "utilities.h"
int main() {
int rc;
char str[20];
rc = getLine("Enter string: ", str, sizeof(str));
if(rc == NO_INPUT) {
printf("[ERROR] No input\n\n");
} else if(rc == TOO_LONG) {
printf("[ERROR] Input is too long\n\n");
} else {
printf("This is your input: \"%s\"\n\n", str);
}
system("pause");
}
Here's utilities.h:
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
int getLine(const char *msg, char *buff, size_t len) {
if(msg != NULL) {
printf("%s", msg);
fflush(stdout);
}
if(fgets(buff, len, stdin) == NULL /*[+]*/ || strcmp(buff, "\n") == 0) {
//[-] fflush(stdin);
return NO_INPUT;
} else if(buff[strlen(buff)-1] != '\n') {
//[-] fflush(stdin);
return TOO_LONG;
} else {
buff[strlen(buff)-1] = '\0';
//[-] fflush(stdin);
return OK;
}
}
And here's the output:
Enter string:
This is your input: ""
Press any key to continue . . .
I solved my problem by replacing the first if statement in utilities.h with if(fgets(buff, len, stdin) == NULL || strcmp(buff, "\n") == 0). Doing this, my program will check for input errors OR for empty strings and return the NO_INPUT flag.
Thanks to everybody who commented and #Peter for answering. I added the aforementioned if statement in utilities.h and removed every fflush(stdin) occurrence. The code now looks as above.
Your problem that you "fixed" is believing that a end of line should be treated as end of input.
NULL is an indication from fgets() that it encountered an error or the end of input when reading from the file (or stream). A blank line is neither an error nor a marker of end of input. A human (typing on a keyboard) might choose to interpret a newline as end of input, but a computer program does not - after all, there is nothing stopping a user entering more than one line of input.
Practically, fgets() reads a line and indicates the end of that line with a '\n' character. Let's say, we have a file containing
ABC
DE
FGHIJ
(blank lines interspersed in three lines of text, followed by end of the file).
Let's also that buffer is an array of five char, and that we read that file using consecutive statements of the form fgets(buffer, 5, file).
So what will fgets(buffer, 5, file) do on each call. Well, with 1 representing the first call, 2 representing the second call, etc we will see results of
"ABC\n" stored into buffer;
"\n" stored into buffer; (first blank line)
"DE\n" stored into buffer;
"\n" stored into buffer; (second blank line)
"FGHI" stored into buffer;
"J\n" stored into buffer; and
fgets() returns NULL, and nothing is stored into buffer.
The first six calls will all return &buffer[0] - not NULL - since no error is encountered reading from the file. Even though there are two blank lines in the input. The last line, which is longer than the buffer (with the '\n' counted) is read in two parts.
Incidentally, your code is using fflush(stdin). Unfortunately, fflush() only has defined behaviour on OUTPUT streams or files. Using it on stdin (or any input stream) gives undefined behaviour. If it is actually discarding input (which it does with some implementations of the C standard library), you are getting lucky - there are real-world compilers where the resultant behaviour does not discard input.
I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC
#include <cstdio>
int main()
{
int i;
printf("%d", scanf("%d", &i));
}
Whatever number i input, i get the output:
1
Why is it so?
On success, the scanf function
returns the number of items successfully read.
This count can match the expected number of readings or fewer, even zero, if a matching failure happens.
In the case of an input failure before any data could be successfully read, EOF is returned.
Try this as well:
printf("%d",scanf("%d%d",&i,&i));
You output the result of scanf, which is not the number you enter, but the number of items that are successfully read. The number you enter is stored in i. To output it you would have to write an additional line:
#include <cstdio>
int main()
{
int i;
if (scanf("%d",&i) == 1)
printf("%d", i);
}
scanf() returns the number of items read when it succeeds. Here its reading only one number hence the output is 1 every time regardless of the number.