scanf formatted input does not apply to first character scanned - c

I'm trying to write a program that outputs non-vowel characters (without if statements and using formatted scanf input). The code I currently have does not apply the %*[] ignored characters to the first %c character scanned, but the restriction applies for the other characters. For example, "Andrew" becomes "Andrw" instead of "ndrw". I'm suspecting this could be due to the %c at the beginning. Could someone help me please? :)
#include <stdio.h>
#include <string.h>
int main(void) {
char c;
while (scanf("%c%*[aeiouAEIOU]", &c) == 1)
printf("%c", c);
return 0;
}

The scanf formats are matched in order so %c is matched first for the A. You need to use 2 separate scanfs for this, or precede the loop with the initial-vowel eating scanf:
scanf("%*[aeiouAEIOU]");
while (scanf("%c%*[aeiouAEIOU]", &c) == 1) {
printf("%c", c);
}
The question is is this any clearer and better than
int c;
while ((c = getchar()) != EOF) {
if (! strchr("aeiouAEIOU", c)) {
putchar(c);
}
}
I have an opinionated answer...

Related

read ints from standard input until \n is found

I'm trying to make a function that reads ints from stdin. it has to read until a certain amount of numbers is read (count in example below), or until it finds a '\n'.
Since as far as I am aware scanf (with %d format specifier) ignores newlines, I used getchar and converted the character into the number it should be.
this works but only for 1 digit numbers.
is there any better way to achieve this?
This is my code:
char num = getchar();
while (num != '\n' && count < 9) {
//boring operations that don't matter
num = getchar()
}
Reading via fgets() is better. Continue reading if your must use scanf().
To use scanf("%d",...), we need extra care to read a line. As "%d" consumes leading white-space, including '\n', we need more code to look for white-space and test if a '\n' is found.
int count = 0;
while (count < 9) {
// Read leading spaces
int ch;
while (isspace((c = getchar())) && c != '\n') {
;
}
if (c == '\n' || c == EOF) break; // We are done reading
ungetc(c, stdin); // put character back
int some_int;
if (scanf("%d", &some_int) == 1) {
printf("Integer found %d\n", some_int);
count++;
} else {
// Non-numeric input, consume at least 1 character.
getchar();
}
}
If numeric text is outside the range of int, the above use of "%d" is undefined behavior. For robust code, use fgets().
The %d conversion specifier only ignores leading whitespace. So you can do something like:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
int n = argc > 1 ? strtol(argv[1], NULL, 10) : 10;
int x;
while( n-- && scanf("%d%*[ \t]", &x) == 1 ){
printf("Read: %d\n", x);
int c = getchar();
if( c == EOF || c == '\n' ){
break;
}
ungetc(c, stdin);
}
return 0;
}
However, this will probably not handle a stream like 10 5 x in a reasonable way. You'll need more logic on the first non-whitespace after an integer to handle that (maybe just do if( c == EOF || ! isdigit(c) ){ break; }). Parsing data with scanf if fickle (it really never has a purpose outside of university exercises). Just use fgets and strtol.
scanf() doesn't ignore \n
#include <stdio.h>
#include <stddef.h>
int main(int argc , char *argv[])
{
int b;
char c;
scanf("%d%c",&b,&c);
if(c == '\n') printf("and then " );
}
Someone posted an answer and then deleted but it was the perfect solution for my problem, so all credit to the original author.
The solution was reading normally with scanf and afterwards,with getchar, checking if it was \n or EOF. If it was break out of the cycle, if it wasn't, "unread" with ungetc so you can scanf the number in the next iteration.
So my final code looks like this:
while(scanf("%d",&num) == 1 && count<9){
//boring operations
c = getchar();
if (c == EOF || c == '\n') break;
if (ungetc(c,stdin) == EOF) break;
}
NOTE: like Andrew Henle pointed out in the replies, this doesn't work unless it is guaranteed that there isn't any space between the digits and the newline

Printf w/ Eclipse CDT Issue

Long story short I'm running Eclipse CDT. Below is my code, a simple input character function. However when I run it (without errors*) it requres me to input a character for the variable 'c' before displaying the printf statement. I have tried using a puts statement as well as making two printf lines to no avail. Can someone please direct me to the best solution, or tell me if this is more likely a eclipse cdt issue.
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char c;
printf("Please input a character: %c\n", c = getchar());
if ((c >= 'a') && (c <= 'z'))
printf("%c is a lower-case letter.", c);
else if ((c >= 'A') && c<= 'Z')
printf("%c is a capital letter.", c);
else if ((c >= '0') && c <= '9')
printf("%c is a digit!", c);
return EXIT_SUCCESS;
}
Thank you for any and all help!
These two lines:
char c;
printf("Please input a character: %c\n", c = getchar());
are not correct and are the reason you have to input a char before the print occurs.
The following will work correctly:
int c;
printf("Please input a character: ");
fflush( stdout );
c = getchar();
You might also want to look at:
isupper()
islower()
isdigit()
which are (normally) found in <ctypes.h>
In your code, you have c = getchar()as a parameter to printf. This parameter has to be evaluated before printf can be called.
You might have better luck using:
printf("Please input a character\n");
c = getchar();
Although, as I read the comments added above, it sounds like there may be a buffering problem as well that will prevent the output from being written. But try this first.

How do I print this in C?

Hi I'm relatively new to programming so please bear with me.
I would like to make a program that takes the input bcdefghijklmnopqrstuvwxy and outputs
else if (c == 'x')
++nx;
where x is a letter of the input, and where the output is repeated for each letter of the input.
This is what I have written so far:
#include <stdio.h>
main() {
int c;
while((c = getchar()) != EOF) {
printf("else if (c == '%d')\n", c);
printf("\t++n%d;\n", c);
}
return 0;
}
Instead of returning the output I want, the output is
else if (c == '98')
++n98;
else if (c == '99')
++n99;
else if (c == '100')
++n100;
else if (c == '101')
++n101;
else if (c == '102')
++n102;
...
Why is c not working as a variable?
Thanks so much for your help!
You want c == '%c' to compare by character or c == %d (without the single quotes) to compare by ordinal value, but you should really learn to use arrays. It looks like you are trying to code something the hard way, and use a code generator to save you some typing. Instead:
int n[256] = {0}; /* storage for counters, initialized to zero */
and:
n[c]++; // increment the counter for character c;
You're code will be much shorter.
When writing in C and printing a string pointed by format to stdout you'll need to make sure you're using the right format specifiers. This will ensure that your argument is formatted correctly and inserted into the resulting string as you would expect.
In your case, you need to use %c. However, you have %d currently, which is the equivalent to %i for integers. You can google more on format specifiers to learn more about other options as well.
Here's an interesting read on the subject:
http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output
You used %d in your printf but %d if for integers. You want to print a char so it should be %c.
Replace %d by %c
More on this link: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/format.html
Try:
#include <stdio.h>
main() {
char c;
while((c = getchar()) != EOF) {
printf("else if (c == '%c')\n", c);
printf("\t++n%c;\n", c);
}
return 0;
}
what you want is characters not ints
Try using
printf("else if (c == '%c')\n", c);
printf("\t++n%c;\n", c);
See printf specifiers
The %d specifier is for intergers

Program is not looping

I am trying to make the program print out "OK" for as long as i enter 'y' as a choice at the end, but it is not looping, it just prints out "OK" and ends the program even if i enter a 'y' at the end. Please help.
#include <stdio.h>
int main()
{
char c = 'y';
while (c == 'y')
{
printf_s("OK\n");
scanf_s("%c", &c);
if (c != 'y')
{
break;
}
}
return 0;
}
On first iteration when you press Enter key then a newline character \n is passed to the input along with y. On second iteration scanf_s reads \n.
Change
scanf_s("%c", &c);
to
scanf_s(" %c", &c);
^Notice the space before %c
A space before %c specifier can consume any number of white-space characters.
Change the scanf_s line as follows
scanf_s("%c", &c, 1);
This extra parameter is specifying the size of the c argument. Plain old scanf doesn't require this argument but the versions ending with _s do
Also the if block with the break statement is unnecessary because the conditional on the while loop effectively does the same thing. It could be written as follows
while (c == 'y')
{
printf_s("OK\n");
scanf_s("%c", &c, 1);
}
OK I used scanf instead of scanf_s, that solved the problem, thanks everyone.
You are wrong with scanf
if you use like this u will see it is working ..
#include <stdio.h>
int main()
{
int c = 1;
while (c == 1)
{
printf_s("OK\n");
scanf_s("%d", &c);
if (c != 1)
{
printf_s("hello\n");
continue;
}
}
return 0;
}
Put a space before %c to skip whitespace.

How to read from input until newline is found using scanf()?

I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter.
If I do this:
scanf("%2000s %2000s", a, b);
It will follow the 1st rule but not the 2nd.
If I write:
I am smart
What I get is equivalent to:
a = "I";
b = "am";
But It should be:
a = "I";
b = "am smart";
I already tried:
scanf("%2000s %2000[^\n]\n", a, b);
and
scanf("%2000s %2000[^\0]\0", a, b);
In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want.
In the 2nd one, it won't compile. According to the compiler:
warning: no closing ‘]’ for ‘%[’ format
Any good way to solve this?
scanf (and cousins) have one slightly strange characteristic: white space in (most placed in) the format string matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.
This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.
One way to deal with that is something like this:
scanf("%2000s %2000[^\n]%c", a, b, &c);
if (c=='\n')
// we read the whole line
else
// the rest of the line was more than 2000 characters long. `c` contains a
// character from the input, and there's potentially more after that as well.
Depending on the situation, you might also want to check the return value from scanf, which tells you the number of conversions that were successful. In this case, you'd be looking for 3 to indicate that all the conversions were successful.
scanf("%2000s %2000[^\n]", a, b);
use getchar and a while that look like this
while(x = getchar())
{
if(x == '\n'||x == '\0')
do what you need when space or return is detected
else
mystring.append(x)
}
Sorry if I wrote a pseudo-code but I don't work with C language from a while.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main(void)
{
int i = 0;
char *a = (char *) malloc(sizeof(char) * 1024);
while (1) {
scanf("%c", &a[i]);
if (a[i] == '\n') {
break;
}
else {
i++;
}
}
a[i] = '\0';
i = 0;
printf("\n");
while (a[i] != '\0') {
printf("%c", a[i]);
i++;
}
free(a);
getch();
return 0;
}
I am too late, but you can try this approach as well.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i=0, j=0, arr[100];
char temp;
while(scanf("%d%c", &arr[i], &temp)){
i++;
if(temp=='\n'){
break;
}
}
for(j=0; j<i; j++) {
printf("%d ", arr[j]);
}
return 0;
}
#include <stdio.h>
int main()
{
char a[5],b[10];
scanf("%2000s %2000[^\n]s",a,b);
printf("a=%s b=%s",a,b);
}
Just write s in place of \n :)
//increase char array size if u want take more no. of characters.
#include <stdio.h>
int main()
{
char s[10],s1[10];
scanf("\n");//imp for below statement to work
scanf("%[^\n]%c",s);//to take input till the you click enter
scanf("%s",s1);//to take input till a space
printf("%s",s);
printf("%s",s1);
return 0;
}

Resources