What's wrong with my program (scanf, C++)? - c++

What wrong with this program?
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
using namespace std;
int N;
char x[110];
int main() {
scanf("%d", &N);
while (N--) {
scanf("0.%[0-9]...", &x);
printf("the digits are 0.%s\n", x);
}
return 0;
}
this is a console application in VS 2013, here is a sample input and output:
input :
1
0.123456789...
output
the digits are 0.123456789
but when I input this to this the output I get : The digits are 0
I have tried inputitng and manually and by text, in Code::Blocks and VS 2013, but neither worked. And when inputting manually, the program doesn't wait for me to input the numbers after I have entered N.
What should I do?

The scanf() in the loop fails, but you didn't notice. It fails because it can't handle a newline before the literal 0. So, fix the format string by adding a space, and the code by testing the return value from scanf():
if (scanf(" 0.%[0-9]...", x) != 1)
…oops — wrong format…
The blank in the format string skips zero or more white space characters; newlines (and tabs and spaces, etc) are white space characters.
You also don't want the & in front of x. Strictly, it causes a type violation: %[0-9] expects a char * but you pass a char (*)[100] which is quite a different type. However, it happens to be the same address, so you get away with it, but correct code shouldn't do that.

Replace
scanf("0.%[0-9]...", &x);
with
scanf(" 0.%[0-9]...", x);
You need to provide the starting location of the array which is x, not &x. Also, the space at the beginning will read all the whitespace characters and ignore it. So the \n left by scanf("%d", &N); is ignored.

Related

Printf display only one word

I want to display more than one word using printf, Do I should change first parameter in pritnf?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int value;
printf("How many:"); scanf("%d", &value);
char* arr1 = new char[value];
scanf("%s[^\n]", arr1);
printf("%s", arr1);
delete [] arr1;
return 0;
}
As already pointed out in the comments section, the following line is wrong:
scanf("%s[^\n]", arr1);
The %s and %[^\n] are distinct conversion format specifiers. You seem to be attempting to use a hybrid of both. If you want to read a whole line of input, you should use the second one.
However, even if you fix this line, your program will not work, for the following reason:
The statement
scanf("%d", &value);
will read a number from standard input, but will only extract the number itself from the input stream. The newline character after the input will not be extracted.
Therefore, when you later call
scanf("%[^\n]", arr1);
it will extract everything that remained from the previous scanf function call up to the newline character. This will result in no characters being extracted if the newline character immediately follows the number (which is normally the case).
Example of program's behavior:
How many:20ExtraInput
ExtraInput
As you can see, everything after the number up to the newline character is being extracted in the second scanf function call (which is then printed). However, this is not what you want. You want to extract everything that comes after the newline character instead.
In order to fix this, you must discard everything up to and including the newline character beforehand. This must be done between the two scanf function calls.
#include <stdio.h>
int main()
{
int value;
int c;
printf("How many:"); scanf("%d", &value);
char* arr1 = new char[value];
//discard remainder of line, including newline character
do
{
c = getchar();
} while ( c != EOF && c != '\n' );
scanf("%[^\n]", arr1);
printf("%s", arr1);
delete [] arr1;
return 0;
}
The program now has the following behavior:
How many:20ExtraInput
This is a test.
This is a test.
As you can see, the program now discards ExtraInput and it correctly echoes the line This is a test.

how scanf handles standard input vs pipelined input

In the following code:
#include <cstdio>
using namespace std;
int N;
char x[110];
int main() {
scanf("%d\n", &N);
while (N--) {
scanf("0.%[0-9]...\n", x);
printf("the digits are 0.%s\n", x);
}
}
when I enter the input through file using command
./a.out < "INPUTFILE"
It works as expected but when I enter the input through std input it delay the printf function.
Why is that?
Input
3
0.1227...
0.517611738...
0.7341231223444344389923899277...
Output through file
the digits are 0.1227
the digits are 0.517611738
the digits are 0.7341231223444344389923899277
output through standard input
the digits are 0.1227
the digits are 0.517611738
The code is from a book, commpetitive programing 3 ch1_02_scanf.cpp.
Because there's an extra \n in your scanf format string, it will read and discard ALL whitespaces (spaces, newlines and tabs, if present). There needs to be an indication of the end of a whitespace sequence, so you should either hit Ctrl-D for EOF, or enter another non-WS character that lets scanf stop.
As Sid S suggests, you cam alternatively change your format string like this:
scanf(" 0.%[0-9]...", x);
The program works because when you redirect its stdin to a file, scanf will know if it reaches EOF and terminates the last input. You need to manually give an EOF when you type from console. That's the difference.
Change the second scanf() line to
scanf(" 0.%[0-9]...", x);

skip a specific set of characters scanf is not defined?

I was reading the documentation of scanf function in this page http://en.cppreference.com/w/cpp/io/c/fscanf and I thought I understood it well until I try this
int main(){
char p[100],t[100];
scanf("%s : %s", p, t);
printf("%s %s", p, t);
}
for my input I used test : scanf for me, the result should be test : but I get test scanf where the scanf function skip the : I don't understand why, I think that nowhere explain, can someone explain me?
thanks
From cplusplus.com,
scanf reads data from stdin and stores them according to the parameter format which can only contain a white space character,a non-white space character and format specifier.
Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace
character (whitespace characters include tab, space and newline).
Non-whitespace character, except format specifier (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a %
character) causes the function to read the next character from the
stream.
Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the
type and format of the data to be retrieved from the stream and stored
into the locations pointed by the additional arguments.
So when you claim,
for my input I used test : scanf for me, the result should be
test : but I get test scanf where the scanf function skip the :
you are interpreting it wrong. scanf should skip the :(colon) or any character that you mention as its parameter. So when you provide an input like test CharachtersToSkip me with following code,
int main()
{
char p[100],t[100];
scanf("%s CharachtersToSkip %s", p, t);
printf("%s %s", p, t);
}
scanf will skip the characters and output only test me
Hope its clear.
if wants the out put "s=>test" only, then why you are print "t=>scanf"
just modify the code like that.
int main()
{
char p[100],t[100];
scanf("%s : %s", p, t);
printf("%s", p);
}
From the man page of scanf()
Matches a sequence of non-white-space characters;
The input string stops at white space or at the maximum field
width, whichever occurs first.
In this case, first %s will get the input until the white space character is occur. So your input is test : scanf. It will get the test for first input. Then it will skip the leading spaces, you are mentioning the : in scanf, so it will skip the colon :. Then get the next string.
For more example , try this code
int main()
{
int a;
scanf("%d ",&a);
printf("a:%d",a);
return 0;
}
In this code, scanf() don't end when you are giving the '\n' after the input.
It will wait for other than white space character occurs.

cin.getline(char, int) gets skipped when in a loop

This is the code I have been trying to execute on TurboC++ 3.0 (Yes, I know it's ancient but can't help it), when the program goes into the loop, it skips the value of y every time including the first attempt. Any help would be appreciated but please avoid rubbing salt into wounds by asking why TurboC++ 3.0. Thanks in advance.
void main()
{
int x, z;
char y[10];
for (int i=0;i<5;i++)
{
cout<<"\nX:";
cin >> x;
cout<<"\nY:";
cin.getline(y,10);
cout<<"\nZ:";
cin>>z;
}
for(i=0;i<5;i++)
{
cout<<x<<"\n";
cout.write(y, 10)<<"\n";
cout<<z<<"\n\n";
}
}
and even if I use cin.get(var) where var is a character, i still get weird results like a heart, diamond or even a smiley.
You get weird results because you are not terminating your c style string with a null character.('\0').
The problem you are facing is because , fail bit or eof bit is set. To remove that, do the following:-
You can use
cin.clear() ;
to clear if any error bits are set and then use
cin.ignore(100, '\n') ;
// 100 is just a random no, change it depending on your size of input.
to ignore any irrelevant characters int the stream.
or you can do the following:-
after cin>>x just type cin.ignore(), it will flush out any newline characters present in the buffer .
it skips the value of y
cin >> x reads the input until it finds something that's not a digit - in this case, the end-of-line character. That character is left in the stream.
getline reads the input until it finds an end-of-line character (or the end of the stream). Since you've left one in the stream, it finds it straight away and doesn't read anything.
You can call cin.ignore(-1,'\n') to ignore the remainder of the first line after reading x (assuming your prehistoric library behaves like the modern one).
i still get weird results like a heart, diamond or even a smiley
cout.write(y, 10) is wrong - there are up to 9 valid characters in y, followed by the null terminator. You want cout << y to treat it as a null-terminated string and print only the valid characters.

What is wrong with my UVa code

I tried to solve this problem in UVa but I am getting a wrong answer and I cant seem to find the error
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2525
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,j,k,i=1;
char a[1000];
while(scanf("%d",&t)!=EOF && t)
{
int sum=0;
getchar();
gets(a);
k=strlen(a);
for(j=0;j<k;j++)
{ if(a[j]=='a'||a[j]=='d'||a[j]=='g'||a[j]=='j'||a[j]=='m'||a[j]=='p'||a[j]=='t'||a[j]=='w'||a[j]==32)
sum=sum+1;
else if(a[j]=='b'||a[j]=='e'||a[j]=='h'||a[j]=='k'||a[j]=='n'||a[j]=='q'||a[j]=='u'||a[j]=='x')
sum=sum+2;
else if(a[j]=='c'||a[j]=='f'||a[j]=='i'||a[j]=='l'||a[j]=='o'||a[j]=='r'||a[j]=='v'||a[j]=='y')
sum=sum+3;
else if(a[j]=='s'||a[j]=='z')
sum=sum+4;
}
printf("Case #%d: %d\n",i,sum);
i++;
}
return 0;
}
In the problem description there is a single number that indicates the number of texts that will be in the input afterwards. Your original code was trying to read the number before every row of input.
The attempt to read the number in each one of the rows will fail since the input character set does not include any digits, so you could be inclined to think that there should be no difference. But there is, when you try to read a number it will start by consuming the leading whitespace. If the input is:
< space >< space >a
The output should be 3 (two '0' and one '2' keys), but the attempt to read the number out of the line will consume the two leading whitespace characters and the later gets will read the string "a", rather than " a". Your count will be off by the amount of leading whitespace.
separate your code into functions that do specific things: read the data from the file, calculate the number of key presses for each input, output the result
Benefit:
You can test each function independently. It is also easier to reason about the code.
The maximum size of an input is 100, this means you only need an array of 101 characters( including the final \0) for each input, not 1000.
Since this question is also tagged C++ try to use std::vector and std::string in your code.
The inner for seems right at a cursory glance. The befit of having a specialized function that computes the number of key presses is that you can easily verify it does the correct thing. Make sure you check it thoroughly.