Implement the Unix 'dc' utility in C [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am just hoping on getting some tips on how to get started on my assignment.
It reads as follows:
"Implement a program that behaves similarly to the 'dc' utility, which evaluates expressions in a postfix notation, and also supports additional computations using variables and macro strings. Feel free to experiment with the existing utility and consulting its manual pages.
The assignment will support only a subset of the complete utility:
-- all numeric values will be integers, only using radix 10
-- numbers may be assumed to be within the range of 32-bit signed numbers
-- all register names will be alphanumeric (a subset of those dc allows)
-- no command line options or arguments will be required
-- only the following commands are are required (listed in the same order as the manual)
p n f + - * / % ^ c d r s l S L x > !> < !< = != q #
Some key differences between the assignment and the existing utility:
-- all input will be through standard input only (but not necessarily keyboard)
-- register stacks are initially not empty, but filled with infinite zeros
-- the q command will exit the program, regardless of macro call nesting level
-- additional spaces may appear between input tokens for legibility
(the space is not a command or a value or a register name)"
I honestly don't know where to start... Any help is greatly appreciated, thanks guys.

As it is an assignment and you do not know where to start here are some hints:
Start with reading the stdin and split it into tokens
implement the stack to store operands and results
implement a few operations like +,-,*,/
make it all working
then implement the missing features one by one

#Serge has given a good outline of how to start, but you seem a bit at sea about just what dc does, so here are a few pointers for that.
The assignment says that you should experiment with the real dc program. Do this, if you haven't already done so, and you should learn quite a bit. (If you haven't done this, why not?)
Check out the Basic Operations section of the Wikipedia page on dc.
Read the dc man page. You'll find it confusing the first time, but read it again and try out what you see there with the actual program.
If you're confused by the whole idea of postfix notation see the Wikipedia page on Reverse Polish Notation, which is another name for the same thing.
This should let you understand the following very simple examples, as well as predict what they do:
3 p
3 4 * p
3 4 5 + * p
3 4 + 5 * p
Your assignment goes quite a way beyond, but if you get this much implemented you'll be more than half-way there.

Related

C++/CLI Load variables from a .txt file using a special structure

Rather long question, and quite long story so I'll try to be as quick and precise as I can. I've written a program which allows the user to create questions for a quiz, and those options be exported into a .txt file with the below structure:
#
Level: 1
Ref: testRef
Question: test question
A: test A
B: test B
C: test C
D: test D
Ans: A
APerc: 100
BPerc: 0
CPerc: 0
DPerc: 0
Phone Answer: Right, I know this. The answer is 100% A. Good luck!
50/50: B
50/50 Percentage 1: 100
50/50 Percentage 2: 0
Force: True
!
Where
# indicates the start of the question,
Level is the part of the quiz this question is worth (the higher it is, the more difficult it is),
A, B, C and D are the alternative answers,
ans is the correct answers,
APerc to 50/50 Percentage 2 are all info for assists to the user to answer the question if they use them,
the value of force is whether this question should appear definitively or not, since their may be more than once question with the same level
and ! indicates the end of a question.
Now, in terms of code what would be the easiest way to read the whole file and identify each of these individual questions with the aforementioned delimiters?
Would it be good to use something like StreamReader? I'd rather read the whole file, then identify if any questions have been forced, then randomly pick 15 questions, either at the start of runtime or during the reveal of the next question, with different levels, possibly passing the value of the current level to the read function and then store all the question info in variables.

Calculating input.

I tried to make a code that calculates the values of the formulas the user inputs. I.e , if user inputs "10+5" , the program would print "The sum is 15" etc. At first, i thought this is a easy thing to do, but if realized that just using scanf orsth wouldn't do the trick. Then i messed around with arrays and loops to see if the loop encounters "-" or "+" signs in input and then saving the character before "-" or "+" and after it and then calculating it, but i couldnt make this work either.
Could you please lead me in the right direction on how to get this done.
Thank you very much!
This can be quite complicated, especially when you get to operator precedence and you need to correctly calculate, for example, 2 + 5 * 6, which needs to be treated as 2 + (5 * 6). The correct way to approach this is to construct an expression tree (just like a compiler would). e.g.
+
/ \
2 *
/ \
5 6
You do this by creating binary tree. Each nodes holds an operation and (up to) two subnodes. Then you evaluate your expression by traversing the expression tree.
What you are trying to do is to parse arithmetic expressions, then evaluate them. There is a ton of stuff on this on the internet so, since this is your homework, I'll leave you to Google. Your first thought, that this would be easy to do, is probably a naive thought, though it's not a terribly difficult problem if you don't get too ambitious too quickly.
This might be a little over your head, but what you can do is use a grammer engine for c and a lexical analyzer.
I believe it is called "BISON" and "YYLEX"
From what I remember in school, it is how we made our pascal compiler.
http://en.wikipedia.org/wiki/GNU_bison
After creating a tree. you then can analyze sub trees and then the root node will be the sum of the sub trees.
These might be some steps that you might want to consider
get the input using getline() or fgets()
start reading the string from the beginning
do two passes, use one queue for operators and another for operands (numbers)
during the first pass, you reach an * or /, read the next number, perform the operation on the next number and the number you read before, and insert the result in a queue
also during the first pass, if you read a + or -, silently push the operator and operands into their respective queues
during the second phase handle + and -... using queues will help you properly handle successive minuses e.g. 4-3-3
These are not EXACT steps, but it's a heuristic worth looking into - try to work through these, change them according to what makes sense to you etc.

What does the "k" stand for in Cocoa constant names [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does the 'k' prefix indicate in Apple's APIs?
Objective C - Why do constants start with k
For example, the result codes defined for Audio Format Services:
kAudioFormatUnspecifiedError
kAudioFormatUnsupportedPropertyError
etc...
What does that leading k stand for? I've always assumed key, since such constants are often used as the keys in dictionaries, but those result codes are an example of where the constant is just a return value, not (as far as a client of the API can determine) a key.
I imagine that it merely stands for 'k'onstant, where 'k' is used because 'c' is already commonly used to indicate class or in Hungarian notation character.
The usage has historical precedent; early pocket calculators used 'k' to indicate constant mode (where repeated operation of = repeated the last operation) because 'c' was used for clear.
You can find the answer here.
Answer one
Constant names (#defines, enums, const local variables, etc.) should start with a
lower-case k and then use mixed case to delimit words, i.e.
kInvalidHandle, kWritePerm.
Though a pain to write, they are absolutely vital to keeping our code
readable. The following rules describe what you should comment and
where. But remember: while comments are very important, the best code
is self-documenting. Giving sensible names to types and variables is
much better than using obscure names and then trying to explain them
through comments.
But it has since been removed in the live version of the document. It
should be noted that it goes against the the Official Coding Guidelines
for Cocoa from Apple.
Cocoa coding guidelines
It was the coding standard left over when Apple used pascal. K was the prefix as opposed to all caps for other C languages.

A newbie question regarding making an executable program [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I’m a student of other discipline. I would like to make an executable program on my own. Suppose the program I would like to make is a small dictionary with a few thousands of words. In the hope of creating such a program in my Windows XP, I collected a compiler called Borland C++ V.5.02. I downloaded some books on C language like Programming Language (2nd Edition) by Brian W. Kernighan, Dennis M. Ritchie; Sams Teach Yourself C in 24 Hours, and Programming with C (2nd edition) by Byron S. Gottfried. I started reading those books but sooner I found there were no instruction how to make such a program or I was unable to understand from those huge contents. I’m expecting some instruction from you all telling how I should proceed. Please leave some comments to help me out create such type of program.
C is not the friendliest language to learn on your own if you have no notions of computer architecture.
Maybe something like Python is more suitable?
I'm sure you can download lots of Python books :-)
Welcome to programming. :)
It might be easier to think of your problem in small pieces:
How will you store your dictionary?
Plain text, any order -- simple to work with, slower
Plain text, sorted -- requires sorting the word list (easy with a sort utility, but you or your users have to remember to sort the list); faster
A binary version (say, 32-byte 'records' for words): much harder to edit, but fast lookups
A binary encoding of a tree structure, child nodes are allowed character transitions: requires tools to create, very fast lookups
clever hashing http://en.wikipedia.org/wiki/Bloom_filters can go very very quickly.
Once you've picked the storage (I suggest plain text, any order, as a good starting point) you'll need to figure out the algorithm:
For a given word, compare it against every single word in the file
So you'll need to read ever line in the file, one at a time (fgets in a loop)
Compare the word with the line (strcmp)
return 1 if found
return 0 if you reach the end of the file
Now, iterate this, once for each word in the input:
read in a line (fgets)
tokenize the string into words (strtok)
strip off punctuation (or ignore? or ...)
pass the word to the routine you wrote earlier
This is an awful dictionary program: for a dictionary of 100,000 words (my /usr/share/dict/words is 98,000, and I think the wordlist on OpenBSD systems is in the 150,000 range) and a document of 5,000 words, you'll run your inner loop roughly 250,000,000 times. That'll be slow on even fast machines. Which is why I mentioned all those much-more-complex data structures earlier -- if you want it fast, you can't do naive.
If you sort the word list, it'll be roughly 83,000 comparisons in your inner-loop.
(And now a small diversion: the look program supports a -b option to ask for a binary search; without the -b, it runs a linear search:
'help' 'universe' 'apple'
linear .040s .054s .058s
binary .001s .001s .001s
In other words, if you're going to be doing 5,000 of these, sorted word list will give you much faster run times.)
If you build a finite-state machine (the tree structure), it'll be as many comparisons as your input word has characters, times 5000. That'll be a huge savings.
If you build the bloom filters, it'll be computing one or two hashes (which is some simple arithmetic on your characters, very quick) and then one or two lookups. VERY fast.
I hope this is helpful, at least the simpler versions shouldn't be hard to implement.
Programming is not the easiest thing to do, despite some people think so. It takes a lot of time to learn and master so if you really considering creating your own application a lot of patience and time is required.
If you want to use this application of yours to learn programming then I'd suggest find some tutorials for particular language and digg in.
If it's something you'd need for your main discipline maybe you could hire somebody to create such app for you, or browse sourceforge.net for similar solution, or find commercial alternative.
And yes, it's hard in the beginning :)
If you want to learn C++ then you can use Microsoft Visual C++ Express which is free. Creating of executable program is pretty straightforward task. Look at Visual C++ Guided Tour

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