0

I've been writing a program operating on some stdin data a viatal and basically the last part of which is a for / while loop that causes a slight but totally unaccountable problem.

The thing is that even though it gives a good answer and simply works perfectly well on i.e. on idone.com it gives a bug on my Visual Studio or on spoj.com. The bug is that after I paste some data to my console (in my VS) there's no output until I give a letter or any other non-white sign and press enter. The output (correct of course) doesn't shows until then. As it goes about spoj.com I see an error information that the time limit has been exceeded but I'm pretty sure that the problem is the same - for some reason the program is listening for one more sign.

So if the sign doesn't directly influence the output, why do I have to put any sign and click enter to show the answer? I'm still far from being a pro programer so I'll really appreciate any help from You Guys.

Thanks in advance!

(...)
   for (int i = 0; i < numberOfOperations; i++)
    {

        scanf("%d%d", &leftSetRowNr, &rightSetRowNr);
        char n;
        n = getchar();
        if((currentSum %2) == 0)
        {
            copyToMainTab(resultTab, mainTab,leftSetRowNr, mainTabCurrentInd);
        }
            else if (currentSum%2 != 0)
            {
                copyToMainTab(resultTab, mainTab,rightSetRowNr, mainTabCurrentInd);
            }

        quickSort(mainTab, 0, (mainTabCurrentInd-1) );

        if(mainTabCurrentInd > trimNumber)
        {
            mainTabCurrentInd = trimNumber;
        }

        int tempSum = 0;
        for(int s = 0; s < mainTabCurrentInd; s++)
        {
            tempSum += mainTab[s];
        }
            currentSum = tempSum;
    }

    int nrOfEl = 1;
    int nr = mainTab[0];
    for (int i = 1; i < trimNumber; i++)
    {
        if (nr != mainTab[i])
        {
            nrOfEl ++;
            nr = mainTab[i];
        }
    }
    printf("%d %d", currentSum, nrOfEl);
return 0;
}    (...)
musztard2000
  • 127
  • 2
  • 14
  • consume the `newline` character that stays in `stdin` buffer by putting `getchar()` under `scanf`. This is not C++ however. – 101010 Jun 08 '14 at 23:02
  • Also remove `\n` from `scanf`. – 101010 Jun 08 '14 at 23:08
  • @40two: It is perfectly valid C++. – Ben Voigt Jun 08 '14 at 23:13
  • @BenVoigt I won't argue, C++ is full backward compatible with mother C. However, using `scanf` in C++ isn't quite popular... – 101010 Jun 08 '14 at 23:15
  • @BenVoigt Yes it is. Still I feel like people writing code like this should beaten with a stick. :) – Baum mit Augen Jun 08 '14 at 23:15
  • @40TWO thank U for Your answer it improved my code so that I don't have to put a non-whit sign. Now, I have to click the `enter` only but it's still wrong for `spoj.com` and my VS compilers... What else can I change? – musztard2000 Jun 08 '14 at 23:17
  • VS complains because `scanf` is unsafe, in VS use `scanf_s`. – 101010 Jun 08 '14 at 23:19
  • Yes that might be true but still `spoj.com` shows the time-limit-exceeded error which means that there still must be something wrong with reading... – musztard2000 Jun 08 '14 at 23:22
  • @BaummitAugen What is so wrong about my code that You would like to beat me with A STICK? :) – musztard2000 Jun 08 '14 at 23:27
  • Have you read this http://www.spoj.com/tutorials/USERS/#submit ? – 101010 Jun 08 '14 at 23:31
  • @vladimir1923 The two most important things: Don't use `printf` and co, but streams like `cout` and `cin` instead (easier and safer). 2nd Break your code down in smaller units and prefer calling functions over nesting loops and branches. It is unnecessarily hard to maintain (i.e. debug / verify correctness ...) your code. – Baum mit Augen Jun 08 '14 at 23:33
  • Why don't you use the default input stream cin >> leftSetRowNr >> rightSetRowNr which is much more convenient than the old-fashioned scanf – tzwickl Jun 08 '14 at 23:36
  • @BaummitAugen Oh, so that was the reason... I can assure You that You can calm down :) because that's a part of a program for my algorithms classes which is supposed to be more structural and the only function that I can call should be of `inline` type. That's also the reason for `scanf` and `printf` functions which are hell more faster than standard streams, yet You can be sure that normally I use safe and more ellegant streams :) – musztard2000 Jun 08 '14 at 23:40
  • @40two Sadly, I've already known that and I'm pretty sure that that my program `hangs up, expecting some input data` as it's written in the manual. Sadly, I've got no clue where... – musztard2000 Jun 08 '14 at 23:44
  • @tom1991te If I could I'd do it with pure pleasure. Unfortunatelly, I've been doing my algorithms classes project which must be as fast as possible and we both know that apart from being more secure and convinient, streams are also much slower. I'm using them all the time, but this time I can't. But even after replacing scanf with your suggestion the bug still persists. I mean that I still have to click enter before seeing the result. – musztard2000 Jun 08 '14 at 23:49
  • @vladimir1923 I doubt that correctly used streams are slower than C I/O. ([Example](http://stackoverflow.com/questions/17468088/performance-difference-between-c-and-c-style-file-io)) – Baum mit Augen Jun 08 '14 at 23:57
  • @BaummitAugen http://codeforces.com/blog/entry/5217 – musztard2000 Jun 09 '14 at 00:02
  • @BaummitAugen http://codeforces.com/blog/entry/5217 Where it comes to speed reagardless of any other factors (I'd never doubt that these factors could be many times of even higher importance than speed!) streams are simply less efficient. Every code written for speed has input based on getchar() and this function is almost never used in daily life. – musztard2000 Jun 09 '14 at 00:08
  • @BaummitAugen: iostreams are about 20x slower than `` functions. Sad, but true. iostreams can't transfer data to its own buffers fast enough to keep up with a hard disk. http://stackoverflow.com/q/4340396/103167 – Ben Voigt Jun 09 '14 at 03:54
  • @vladimir1923: `getchar()` is the slowest tool in the `` toolbox. Block transfers are much faster. OS functions and memory-mapped files are even faster yet. – Ben Voigt Jun 09 '14 at 03:56
  • @benVoigt Wow, I'd never excpect something like that. I've been always told that for reading input like integers (on which I'm operating most of the time on my algorythmic classes) it is faster to use custom functions based on `getchar()` than to use streams based functions. The reason seemed to be reasonable - custom functions weren't so overloaded, so under the skin there was happening much less than it 's happening with streams. And from my experience replacing `cin` with `scanf` reduced time of execution by about 20% and replacing them with `getchar()` gave next 10-15%... – musztard2000 Jun 09 '14 at 08:27
  • @BenVoigt But anyways, I'm still learning and I'm eager to know more stuff every day so I believe that U could answer my question - what should I use to read data such as integers in the fastest way? `cin` seemes to be far in the back of the competition so what sort of method should be best? And could U briefly tell me what makes that function the fastest? Is it buffering? – musztard2000 Jun 09 '14 at 08:31
  • @vladimir1923: If you have to support arbitrary file-like objects, including ttys, then use the OS `read` function (`read` is the POSIX name, on Windows it is `ReadFile`) to grab a block of data. The same character-by-character processing used with `getchar()` is still effective, but if you don't want to reinvent the wheel, use `strtol` and `strtod`. They are well-tested and quite fast. Boost::Spirit's parsers are faster yet. – Ben Voigt Jun 09 '14 at 22:10
  • @vladimir1923: You'll save yourself a lot of headaches if you separate I/O from data processing. The problem with `cin` and `fscanf` is that they do both. Your speed gains with `getchar()` were because you used faster processing. Put that fast processing together with fast block I/O for the best results. – Ben Voigt Jun 09 '14 at 22:12
  • @BenVoigt Thank U very much for this great piece of knowledge, I'll try it for sure! I'd be even more grateful, if U could tell me one more thing. Going back to my program a snippet of which I've posted - what should I change to see a result (let's say in Visual Studio) just after pasting an exemplary data to my console window? I mean I'd like to just paste the data and to see te result - since the program should print it just after it finishes processing the input. Do You think that is there anything I can do? From what I've tried simple replacing `for` loop with `while` haven't worked... – musztard2000 Jun 09 '14 at 23:02
  • @vladimir1923: Paste to console acts like keyboard input... but I think you maybe should try building a simple GUI with two textboxes (data in, results out) and two buttons (process, exit). And you can make the paste message perform processing automatically. – Ben Voigt Jun 09 '14 at 23:07
  • @BenVoigt Sadly, the program has to be 100% console-like. It's mainly an algorytmic problem - already solved - but the implementation in this case is most troublesome for me. The concept seems simple: after I receive some data which I store in a two-dim array I'm doing some operations on it. The number of them is fixed and makes the limit in my for loop. So not to store all the operations my intent is to dynamically load one instruction after another and to perform operations. The whole program always gives good results on ideone.com but on spoj or my VS it seems to expect one more sign... – musztard2000 Jun 09 '14 at 23:18

0 Answers0