Test Cases of atof() function in structure format - c

Two days ago i attended an interview.I had been asked a question and i am still finding answer.The Question Was tell me the test cases of atof(const char *str) function in c.I told him various test cases like
I have to check the given string should contain only numeric.
Given string contain one decimal point.
it should not overflow after conversion.
string should not be null.
but interviewer was not satisfied and asking for give me the answer in structured format.now my question is how to represent this answer in structure format so that in future i could not make same mistake.

I'm not sure what the interviewer means by "structured format", but I would do this by writing down the BNF syntax for floating point numbers (the C language specifies them), and then presenting test cases that test for each path through the syntax. Your cases notably do not cover the sign or exponent, and the number need not contain a decimal point.
A structural approach breaks the problem down into subproblems. Syntax is one subproblem, and the syntax chart or BNF provides a natural way to break that down into subproblems. An additional subproblem is boundary conditions ... there should be test cases for the minimum (> 0) and maximum valid values. There should also be test cases for handling of invalid inputs, but as lundin noted in a comment, that's impossible for atof as the behavior for invalid inputs is undefined.

Maybe you can structure your answer by what you are testing, like giving bad formated string (null, empty, etc ...) and by giving bad arguments like bad "numbers" (0 prefix/suffix 2.0, 0.4 etc...) you can also tests negative float numbers, put more than one dot in the string or whatever. I hope i have answer your question, if not, i think i haven't understood the question well.

I understand the term "test cases" differently than you.
I think what he wants are various inputs to atof and their expected results. For example:
1. atof("1.5") should return 1.5.
2. atof("-7") should retutn -7.0.
3. atof("Hello, world") should fail. But following Lundin's comment, there's no defined failure behavior for atof, so you can't really test this.
The test cases should cover all the different things the function needs to test. But you don't need to write down these things - just the example inputs and expected outputs.
Writing this in a structured format is easy.

We used use atof in our code most of the time we need to handle Internationalization/Localization in many languages 10.0 get converted to 10,0.
before calling atof you need to set locale and after completing the functionality you have to reset the locale.

Related

How to evaluate if a code is correct against a submitted solution

I´m searching information about how to compare two codes and decide if the code submitted by someone is correct or not (based on a solution code defined before).
I could compare the output but many codes may have the same output. Then I think I must compare someway the codes and give a percentage of similitude.
Anybody can help me?
(the language code is C but I think this isn´t important)
Some of my teachers used online automated program grading systems like http://web-cat.org/
In the assignment they would specify a public api you must provide, and then they would just write tests against your functions, much like unit tests. They would intentionally pick tests that would exploit boundary conditions and other things students are notorious for not thinking about, and just call your code with many different inputs to try to get your code to fail.
Sometimes they would hardcode the expected values, other times they would allow values within a range, and other times they just did the assignment themselves and made it so your own code has to match the results produced by their code.
Obviously, not all programs can be effectively graded this way. It's also kinda error prone in that sometimes even the teacher made a mistake and overflowed an int or something, then the correct student submissions wouldn't match the teachers incorrect results. But, a system doesn't need to be perfect to be useful. But I think this raises an important point in that manually grading by reading the code won't necessarily reveal all mistakes either.
Another possibility is copy the submitted code, strip out all of the white space and search for substrings that must exist for the code to be correct and/or substrings that cannot exist for the code to be considered correct. The troublesome bit might be setting up to allow for some of the more tricky requirements such as [(a or c),((a or b) and c),((a or b) and c)], where the variables are the result of a boolean check as to if the substring related to the variable exists within the code.
For example, [("printf"),("for"), (not "1,2,3,4,5,6,7,9,10")], would require that "printf" and "for" be substrings in the code, while "1,2,3,4,5,6,7,9,10" i I'm not familiar with C, so I'm I'm assuming here that "printf" is required to be able to print anything without involving output streams, which could be accounted for by something like [("printf" or "out"),("for"), (not "1,2,3,4,5,6,7,9,10")], where "out" is part of C code required to make use of output streams.
It might be possible to automatically find required substrings based on a "correct" code, but as others have mentioned, there are alternative ways to do things. Which is why hard-coding the "solution" is probably required. Even so, it's quite possible that you'll miss a required substring, and it'll be marked as wrong, but it's probably the only way you can do what you ask with some degree of success.
Regular expressions might be useful here.

Input/ Output alternatives for printf/scanf

It may sound strange that knowing a lot about iOS and having some experience in .net, I am a newcomer to C. Somewhere I got this target to find average of n numbers without using printf and scanf. I don't want the code for the program but I am seeking alternatives to the mentioned functions.
Is code with printf/scanf required here? Also do let me know if my query stands invalid.
No, neither printf nor scanf is really needed for this.
The obvious alternatives would be to read the input with something like getc or fgets and convert from characters to numbers with something like strtol.
On the output side, you'd more or less reverse that, converting from numbers to characters (e.g., with itoa which is quite common, though not actually standard), then printing out the resulting string (e.g., with fputs).

C homework, ignore for now (I think I am going repost later with some code)

I am going to be making a program that reads in a line and gets up to 6 numbers. The program will eventually solve a a square matrix between 2x2 and 6x6. My question is what errors do I need to look for on the get_numb() function?
I am thinking that the function will have to check character by character to make sure that the individual characters are actual numbers and not a EOF or \n. I will have to also check that there is not more than 6 numbers on a line. I am about a week into programing, so is there anything I need to know to tackle this?
I absolutely recommend you start by taking into use a good unit testing framework, and write unit tests as you go. This way you can cover all the cases you mention above, and make sure that your program really works the way you think it should work.
There are loads of questions on SO about C unit testing frameworks; pick your favourite.
Apart from the cases you mention, I can think of the following:
less than 6 numbers on a line
empty line
(if the numbers are floating point, various number formats)
If your teacher gave you sample input / output, you may of course incorporate that into your unit tests as well.
The potential errors you described are reasonable ones to check for.
I recommend you give it a shot. If they're not sufficient and you get stuck, then post your code and explain what you're seeing.
Most ascii to integer converters will help you out with the error checking. Here's hoping your teacher gave you some example input code and perhaps, depending on the input methods, some example conversion code. As this is homework, I don't want to get too specific.

Test printf implementation

I would like to have a portable implemenation of my application. However,
I have heard that there are some issues with printf from the stdlib on certain machines
where it does not behave as intended. For instance, when using the conversion specifier
%f then it can happen that on certain architectures the printf implementation
includes a decimal point in the output!
Now I am wondering, if there are maybe some testing routines out there which I could
use to test the semantic correctness of stdlib c implementation, in particular the printf
routine. Maybe there are some good resources that point out some issues when porting programs?
Many thanks,
Heinz
I think Postel's law ("be conservative in what you do, be liberal in what you accept from others") applies here, too. Don't write your tests to require a character-by-character match in order to consider the printf() implementation to be working.
Instead, do it a a higher level; parse the text output by printf() into the expected datatype, and compare against a value of that type.
I.e., if printing "2.25", parse the text (using strtod() or equivalent) and compare against the actual number 2.25, not the literal text string "2.25".
The wine test suite for the msvcrt dll looks interesting : http://github.com/mirrors/wine/blob/master/dlls/msvcrt/tests/printf.c
You should write your own test suite that covers the issues that concern you. It's very simple to call printf 100 times with varying inputs, and the output is simple text, so it's simple to check against the output you expect.
I would recommend to test it in the following way: use sprintf() to produce some testing templates and compare them to your "correct" one.
I did something like this using fprintf (just to avoid the caching in our embedded system).
I think that results would not differ for the printf and sprintf: the formatting algorithm is the same.

How do I align a number like this in C?

I need to align a series of numbers in C with printf() like this example:
-------1
-------5
------50
-----100
----1000
Of course, there are numbers between all those but it's not relevant for the issue at hand... Oh, consider the dashes as spaces, I used dashes so it was easier to understand what I want.
I'm only able to do this:
----1---
----5---
----50--
----100-
----1000
Or this:
---1
---5
--50
-100
1000
But none of this is what I want and I can't achieve what is displayed on the first example using only printf(). Is it possible at all?
EDIT:
Sorry people, I was in a hurry and didn't explain myself well... My last example and all your suggestions (to use something like "%8d") do not work because, although the last number is 1000 it doesn't necessarily go all the way to 1000 or even 100 or 10 for that matter.
No matter the number of digits to be displayed, I only want 4 leading spaces at most for the largest number. Let's say I have to display digits from 1 to 1000 (A) and 1 to 100 (B) and I use, for both, "%4d", this would be the output:
A:
---1
....
1000
Which is the output I want...
B:
---1
....
-100
Which is not the output I want, I actually want this:
--1
...
100
But like I said, I don't know the exact number of numbers I have to print, it can have 1 digit, it can have 2, 3 or more, the function should be prepared for all. And I want four extra additional leading spaces but that's not that relevant.
EDIT 2:
It seems that what I want, the way I need it, it's not possible (check David Thornley and Blank Xavier answers and my comments). Thank you all for your time.
Why is printf("%8d\n", intval); not working for you? It should...
You did not show the format strings for any of your "not working" examples, so I'm not sure what else to tell you.
#include <stdio.h>
int
main(void)
{
int i;
for (i = 1; i <= 10000; i*=10) {
printf("[%8d]\n", i);
}
return (0);
}
$ ./printftest
[ 1]
[ 10]
[ 100]
[ 1000]
[ 10000]
EDIT: response to clarification of question:
#include <math.h>
int maxval = 1000;
int width = round(1+log(maxval)/log(10));
...
printf("%*d\n", width, intval);
The width calculation computes log base 10 + 1, which gives the number of digits. The fancy * allows you to use the variable for a value in the format string.
You still have to know the maximum for any given run, but there's no way around that in any language or pencil & paper.
Looking this up in my handy Harbison & Steele....
Determine the maximum width of fields.
int max_width, value_to_print;
max_width = 8;
value_to_print = 1000;
printf("%*d\n", max_width, value_to_print);
Bear in mind that max_width must be of type int to work with the asterisk, and you'll have to calculate it based on how much space you're going to want to have. In your case, you'll have to calculate the maximum width of the largest number, and add 4.
printf("%8d\n",1);
printf("%8d\n",10);
printf("%8d\n",100);
printf("%8d\n",1000);
[I realize this question is a million years old, but there is a deeper question (or two) at its heart, about OP, the pedagogy of programming, and about assumption-making.]
A few people, including a mod, have suggested this is impossible. And, in some--including the most obvious--contexts, it is. But it's interesting to see that that wasn't immediately obvious to the OP.
The impossibility assumes that the contex is running an executable compiled from C on a line-oriented text console (e.g., console+sh or X-term+csh or Terminal+bash), which is a very reasonable assumption. But the fact that the "right" answer ("%8d") wasn't good enough for OP while also being non-obvious suggests that there's a pretty big can of worms nearby...
Consider Curses (and its many variants). In it, you can navigate the "screen", and "move" the cursor around, and "repaint" portions (windows) of text-based output. In a Curses context, it absolutely would be possible to do; i.e., dynamically resize a "window" to accommodate a larger number. But even Curses is just a screen "painting" abstraction. No one suggested it, and probably rightfully so, because a Curses implementation in C doesn't mean it's "strictly C". Fine.
But what does this really mean? In order for the response: "it's impossible" to be correct, it would mean that we're saying something about the runtime system. In other words, this isn't theoretical, (as in, "How do I sort a statically-allocated array of ints?"), which can be explained as a "closed system" that totally ignores any aspect of the runtime.
But, in this case, we have I/O: specifically, the implementation of printf(). But that's where there's an opportunity to have said something more interesting in response (even though, admittedly, the asker was probably not digging quite this deep).
Suppose we use a different set of assumptions. Suppose OP is reasonably "clever" and understands that it would not be possible to to edit previous lines on a line-oriented stream (how would you correct the horizontal position of a character output by a line-printer??). Suppose also, that OP isn't just a kid working on a homework assignment and not realizing it was a "trick" question, intended to tease out an exploration of the meaning of "stream abstraction". Further, let's suppose OP was wondering: "Wait...If C's runtime environment supports the idea of STDOUT--and if STDOUT is just an abstraction--why isn't it just as reasonable to have a terminal abstraction that 1) can vertically scroll but 2) supports a positionable cursor? Both are moving text on a screen."
Because if that were the question we're trying to answer, then you'd only have to look as far as:
ANSI Escape Codes
to see that:
Almost all manufacturers of video terminals added vendor-specific escape sequences to perform operations such as placing the cursor at arbitrary positions on the screen. One example is the VT52 terminal, which allowed the cursor to be placed at an x,y location on the screen by sending the ESC character, a Y character, and then two characters representing with numerical values equal to the x,y location plus 32 (thus starting at the ASCII space character and avoiding the control characters). The Hazeltine 1500 had a similar feature, invoked using ~, DC1 and then the X and Y positions separated with a comma. While the two terminals had identical functionality in this regard, different control sequences had to be used to invoke them.
The first popular video terminal to support these sequences was the Digital VT100, introduced in 1978. This model was very successful in the market, which sparked a variety of VT100 clones, among the earliest and most popular of which was the much more affordable Zenith Z-19 in 1979. Others included the Qume QVT-108, Televideo TVI-970, Wyse WY-99GT as well as optional "VT100" or "VT103" or "ANSI" modes with varying degrees of compatibility on many other brands. The popularity of these gradually led to more and more software (especially bulletin board systems and other online services) assuming the escape sequences worked, leading to almost all new terminals and emulator programs supporting them.
It has been possible, as early as 1978. C itself was "born" in 1972, and the K&R version was established in 1978. If "ANSI" escape sequences were around at that time, then there is an answer "in C" if we're willing to also stipulate: "Well, assuming your terminal is VT100-capable." Incidentally, the consoles which don't support ANSI escapes? You guessed it: Windows & DOS consoles. But on almost every other platform (Unices, Vaxen, Mac OS, Linux) you can expect to.
TL;DR - There is no reasonable answer that can be given without stating assumptions about the runtime environment. Since most runtimes (unless you're using desktop-computer-market-share-of-the-80's-and-90's to calculate 'most') would have, (since the time of the VT-52!), then I don't think it's entirely justified to say that it's impossible--just that in order for it to be possible, it's an entire different order of magnitude of work, and not as simple as %8d...which it kinda seemed like the OP knew about.
We just have to clarify the assumptions.
And lest one thinks that I/O is exceptional, i.e., the only time we need to think about the runtime, (or even the hardware), just dig into IEEE 754 Floating Point exception handling. For those interested:
Intel Floating Point Case Study
According to Professor William Kahan, University of California at
Berkeley, a classic case occurred in June 1996. A satellite-lifting
rocket named Ariane 5 turned cartwheels shortly after launch and
scattered itself and a payload worth over half a billion dollars over
a marsh in French Guiana. Kahan found the disaster could be blamed
upon a programming language that disregarded the default
exception-handling specifications in IEEE 754. Upon launch, sensors
reported acceleration so strong that it caused a conversion-to-integer
overflow in software intended for recalibration of the rocket’s
inertial guidance while on the launching pad.
So, you want an 8-character wide field with spaces as the padding? Try "%8d". Here's a reference.
EDIT: What you're trying to do is not something that can be handled by printf alone, because it will not know what the longest number you are writing is. You will need to calculate the largest number before doing any printfs, and then figure out how many digits to use as the width of your field. Then you can use snprintf or similar to make a printf format on the spot.
char format[20];
snprintf(format, 19, "%%%dd\\n", max_length);
while (got_output) {
printf(format, number);
got_output = still_got_output();
}
Try converting to a string and then use "%4.4s" as the format specifier. This makes it a fixed width format.
As far as I can tell from the question, the amount of padding you want will vary according to the data you have. Accordingly, the only solution to this is to scan the data before printing, to figure out the widest datum, and so find a width value you can pass to printf using the asterix operator, e.g.
loop over data - get correct padding, put into width
printf( "%*d\n", width, datum );
If you can't know the width in advance, then your only possible answer would depend on staging your output in a temporary buffer of some kind. For small reports, just collecting the data and deferring output until the input is bounded would be simplest.
For large reports, an intermediate file may be required if the collected data exceeds reasonable memory bounds.
Once you have the data, then it is simple to post-process it into a report using the idiom printf("%*d", width, value) for each value.
Alternatively if the output channel permits random access, you could just go ahead and write a draft of the report that assumes a (short) default width, and seek back and edit it any time your width assumption is violated. This also assumes that you can pad the report lines outside that field in some innocuous way, or that you are willing to replace the output so far by a read-modify-write process and abandon the draft file.
But unless you can predict the correct width in advance, it will not be possible to do what you want without some form of two-pass algorithm.
Looking at the edited question, you need to find the number of digits in the largest number to be presented, and then generate the printf() format using sprintf(), or using %*d with the number of digits being passed as an int for the * and then the value. Once you've got the biggest number (and you have to determine that in advance), you can determine the number of digits with an 'integer logarithm' algorithm (how many times can you divide by 10 before you get to zero), or by using snprintf() with the buffer length of zero, the format %d and null for the string; the return value tells you how many characters would have been formatted.
If you don't know and cannot determine the maximum number ahead of its appearance, you are snookered - there is nothing you can do.
#include<stdio.h>
int main()
{
int i,j,n,b;
printf("Enter no of rows ");
scanf("%d",&n);
b=n;
for(i=1;i<=n;++i)
{
for(j=1;j<=i;j++)
{
printf("%*d",b,j);
b=1;
}
b=n;
b=b-i;
printf("\n");
}
return 0;
}
fp = fopen("RKdata.dat","w");
fprintf(fp,"%5s %12s %20s %14s %15s %15s %15s\n","j","x","integrated","bessj2","bessj3","bessj4","bessj5");
for (j=1;j<=NSTEP;j+=1)
fprintf(fp,"%5i\t %12.4f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\t %14.6f\n",
j,xx[j],y[6][j],bessj(2,xx[j]),bessj(3,xx[j]),bessj(4,xx[j]),bessj(5,xx[j]));
fclose(fp);

Resources