Scan characters depending on a pattern - c++

I found this code in a competitive programming book for ICPC. The objective is to scan inputs which have a pattern where there are N numbers like 0.4586... (starting with 0. and terminating with ...). I tried giving the inputs but on pressing enter key the entire while loop executes at once and I don't get the chance to input the numbers. So I tried using spaces but that doesn't work either. Nothing gets scanned in the while loop however the code works fine if I remove the while loop.
Can someone explain this behaviour.
#include <bits/stdc++.h>
using namespace std;
char digits[100];
int main() {
int N;
scanf("%d", &N);
while (N--) {
scanf("0.%[0-9]...", &digits);
printf("the digits are 0.%s\n", digits);
}
}

Related

Code excerpt freezes unexpectedly only when with full code

What is causing my code to behave unexpectedly?
The program is freezing (not crashing) before it reaches expected part of the code. The program is fully contained inside main(), and isolating the whole code the expected statement makes it work correctly. Why is it happening?
I was coding a yet poor solution for this codeforces problem, that I was intending to refine little by little. The problem is that curiously my program freezes when reading the input (like if it was an infinite loop, it doesn't crash). I tried both C++ and C++11 on GCC, and both of them froze. Tried Ideone, and the same happened. It could be anything, except that I copied everything from the first include to the output line that would confirm that all the input was read and ran only this excerpt.
#include <bits/stdc++.h>
using namespace std;
typedef unsigned uint;
int main() {
ios_base::sync_with_stdio(false);
uint n, h, k, buf;
vector<uint> potatoes;
cin >> n >> h >> k;
for (uint i = 0; i < n; ++i)
{
cin >> buf;
potatoes.push_back(buf);
}
cout << "Letf\n";
return 0;
}
This is a reduced version that contains all the lines that are part of the logic of the input stage. The expected input is
5 6 3
5 4 3 2 1
Here are the links for the full code and the correctly working excerpt.
The main problem is your while (true) {...}. Your "algorithm" makes this loop infinitely.
And if you don't know, there is an Tutorial and source code for the round already
http://codeforces.com/blog/entry/45181
Finally, please look carefully at the problem page. The Contest Materials part have useful things for you.

Query regarding SPOJ TEST

I might be wrong in asking an SPOJ problem on this forum but I wanted to understand one mechanism which I wanted to know from the enriched community here.
Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.
Example
Input:
1
2
88
42
99
Output:
1
2
88
My Solution:
#include <iostream>
using namespace std;
int main()
{
int n,i=0;
int a[100] = {0};
while((cin>>n))
{
a[i] = n;
i++;
continue;
}
for(int j = 0;a[j]!=42;j++)
cout<<a[j]<<endl;
return 0;
}
Good Solution:
#include <iostream>
using namespace std;
int main()
{
int n;
while(true)
{
cin>>n;
if(n == 42)
break;
cout<<n<<endl;
}
return 0;
}
My query is what happens to the input in the good solution?We would be running the loop only till the number is not 42.How does Good solution handle the remaining input?I got some hint that it is somewhat related to buffering and all.Please provide me some explanation or links or study material or at least some keyword to google etc to get clarity on this.
Remaining input in good solution will be ignored by "good solution".
If you need more info read:
object
std::cin
extern istream cin;
Standard input stream
Object of class istream that represents the standard input stream oriented to narrow characters (of type char). It corresponds to the C stream stdin.
The standard input stream is a source of characters determined by the environment. It is generally assumed to be input from an external source, such as the keyboard or a file.
object
stdin
FILE * stdin;
Standard input stream
The standard input stream is the default source of data for applications. In most systems, it is usually directed by default to the keyboard.
stdin can be used as an argument for any function that expects an input stream (FILE*) as one of its parameters, like fgets or fscanf.

Writing a postfix calculator with a stack and iterator

#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
string blah("512+4*+3−");
stack<int> astack;
int a=0;
int b=0;
int result=0;
int final=0;
for (string::iterator count=blah.begin(); count != blah.end(); count=count+1)
{
if (isdigit(*count))
{
astack.push(*count);
cout<<" "<<*count<<" ";
}
else
{
a=astack.top();
astack.pop();
b=astack.top();
astack.pop();
if(*count=='+')
{
result = a+ b;
}
else if (*count=='-')
{
result=a-b;
}
else if(*count=='*')
{
result=a*b;
}
astack.push(result);
}
}
final=astack.top();
cout<<final;
}
My problem is whenever I run it, the code seems to segment fault. When I tried running it with the operator commented it the stack seems to pop two values and I'm not really sure why
As PaulMcKenzie pointed out, your minus sign in the blah string is some sort of weird unicode character that looks like a normal minus sign, but it isn't. Since it's some weird unicode character, it is actually being stored in more than one byte in the string's memory, meaning your iterator for-loop is iterating more times than you would expect!
Put a cout << blah.length() << endl; right after you declare blah, and you'll see that the length is more than the expected 9 characters.
Also, this program will not output the right answer even when the problem above is fixed. You need to convert your ascii number characters (which are in the integer range [48,57]) to the equivalent integer values before you do any calculations with them.
If the code you posted is the actual code, then there is an issue with the string you posted.
string blah("512+4*+3−");
That last character after the 3 is not an ASCII minus sign. It is a Unicode character 0x2212. Change this to an ASCII minus and rerun the program.
What may have happened is that you started out with an ASCII minus, copied the text to another app, and the app tries to "fancy up" the minus by replacing it with more aesthetic looking character. Then you may have copied the text from this app back to your source code editor.

What's wrong with my program (scanf, 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.

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.