Read Json From Standard Input, Then Writes to Standard Output
Chapter 3. Creating Modest Tools: Practice one thing and do it well
Every operating system includes small tools.
Small tools written in C perform specialized small tasks , such equally reading and writing files, or filtering information. If y'all want to perform more complex tasks, you can even link several tools together . Merely how are these small tools built? In this chapter, you'll expect at the building blocks of creating small tools. You'll larn how to control control-line options , how to manage streams of data , and redirection , getting tooled upward in no time.
A small-scale tool is a C program that does one job and does information technology well . It might display the contents of a file on the screen or list the processes running on the figurer. Or it might brandish the first 10 lines of a file or send it to the printer. Most operating systems come with a whole fix of small tools that yous can run from the command prompt or the last. Sometimes, when you have a big trouble to solve, you tin pause it down into a series of minor issues, and and then write small tools for each of them.
Note
Operating systems like Linux are mostly made up of hundreds and hundreds of minor tools.
A small tool does one task and does information technology well.
If one small role of your program needs to catechumen data from ane format to another, that'southward the perfect kind of task for a modest tool.
Here's how the program should piece of work
-
Take the GPS from the bike and download the data.
It creates a file called gpsdata.csv with one line of data for every location.
-
The geo2json tool needs to read the contents of the gpsdata.csv line by line...
-
...and then write that data in JSON format into a file called output.json.
-
The web folio that contains the map application reads the output.json file.
It displays all of the locations on the map.
But you're not using files...
The problem is, instead of reading and writing files, your program is currently reading data from the keyboard and writing it to the brandish .
But that isn't good enough. The user won't want to type in all of the information if it's already stored in a file somewhere. And if the data in JSON format is merely displayed on the screen, at that place's no manner the map within the web page will exist able to read information technology.
You need to make the plan work with files . Simply how do you lot do that? If yous want to use files instead of the keyboard and the display, what code will you have to modify? Will you have to alter whatsoever code at all?
Encephalon Power
Is at that place a mode of making our plan apply files without changing code? Without fifty-fifty recompiling it?
Geek Bits
Tools that read data line by line, process it, and write it out again are called filters . If yous have a Unix automobile, or y'all've installed Cygwin on Windows, you already accept a few filter tools installed.
head : This tool displays the first few lines of a file.
tail: This filter displays the lines at the terminate of a file.
sed : The stream editor lets you do things like search and supervene upon text.
You'll see afterwards how to combine filters together to form filter chains .
You can use redirection
You're using scanf()
and printf()
to read from the keyboard and write to the display. But the truth is, they don't talk directly to the keyboard and display. Instead, they use the Standard Input and Standard Output . The Standard Input and Standard Output are created past the operating organisation when the program runs.
The operating organization controls how data gets into and out of the Standard Input and Output. If you lot run a plan from the control prompt or concluding, the operating system will ship all of the keystrokes from the keyboard into the Standard Input. If the operating system reads any information from the Standard Output, past default it will send that information to the display.
The scanf()
and printf()
functions don't know, or care, where the data comes from or goes to. They merely read and write Standard Input and the Standard Output.
Now this might sound like it'southward kind of complicated. After all, why not only take your programme talk straight to the keyboard and screen? Wouldn't that exist simpler?
Well, in that location'southward a very good reason why operating systems communicate with programs using the Standard Input and the Standard Output:
You can redirect the Standard Input and Standard Output so that they read and write information somewhere else, such as to and from files.
You lot can redirect the Standard Input with <...
Instead of entering data at the keyboard, you tin can use the <
operator to read the information from a file.
The <
operator tells the operating system that the Standard Input of the program should be connected to the gpsdata.csv file instead of the keyboard. So you can send the program data from a file. Now you lot just demand to redirect its output .
...and redirect the Standard Output with >
To redirect the Standard Output to a file, you need to use the >
operator:
Because you lot've redirected the Standard Output, you don't come across any data appearing on the screen at all. Merely the programme has now created a file chosen output.json .
The output.json file is the one you needed to create for the mapping application. Let'due south see if it works.
But there's a problem with some of the information...
Your program seems to be able to read GPS information and format information technology correctly for the mapping application. But after a few days, a problem creeps in.
So what happened here? The problem is that there was some bad data in the GPS data file:
Simply the geo2json
program doesn't exercise any checking of the data it reads; it just reformats the numbers and sends them to the output.
That should be easy to set up. Yous need to validate the data.
Brain Power
Report the lawmaking. What do you think happened? Is the lawmaking doing what you asked it to? Why weren't there whatever error messages? Why did the mapping program think that the unabridged output.json file was corrupt?
Geek Bits
If your program finds a problem in the data, information technology exits with a status of 2. But how can yous check that error status after the programme has finished? Well, it depends on what operating system you're using. If y'all're running on a Mac, Linux, some other kind of Unix machine, or if you're using Cygwin on a Windows machine, y'all can brandish the error status similar this:
If y'all're using the Command Prompt in Windows, and so it'due south a little different:
Both commands do the same thing: they display the number returned by the program when it finished.
Introducing the Standard Mistake
The Standard Output is the default way of outputting data from a plan. Merely what if something infrequent happens, like an fault? You'll probably want to deal with things like error messages a footling differently from the usual output.
That'due south why the Standard Error was invented. The Standard Error is a 2d output that was created for sending fault messages.
Human beings generally have two ears and ane oral cavity, merely processes are wired a niggling differently. Every procedure has i ear (the Standard Input) and two mouths (the Standard Output and the Standard Error).
Homo
Process
Let'south run into how the operating arrangement sets these up.
By default, the Standard Error is sent to the display
Recollect how when a new process is created, the operating organization points the Standard Input at the keyboard and the Standard Output at the screen? Well, the operating arrangement creates the Standard Mistake at the aforementioned time and, like the Standard Output, the Standard Mistake is sent to the display by default.
That ways that if someone redirects the Standard Input and Standard Output and so they use files, the Standard Mistake will continue to send data to the display.
And that's really cool, because it ways that fifty-fifty if the Standard Output is redirected somewhere else, by default, whatsoever letters sent down the Standard Error will still exist visible on the screen .
And then you lot can fix the trouble of our hidden error letters by but displaying them on the Standard Error.
But how do you lot do that?
fprintf() prints to a data stream
You've already seen that the printf()
function sends data to the Standard Output. What you didn't know is that the printf()
function is but a version of a more general function called fprintf()
:
The fprintf()
function allows you to choose where you want to send text to. You can tell fprintf()
to transport text to stdout
(the Standard Output) or stderr
(the Standard Mistake).
Permit'south update the code to use fprintf()
With just a couple of small changes, you can go our error messages press on the Standard Error.
That means that the code should at present piece of work in exactly the aforementioned way, except the mistake messages should appear on the Standard Fault instead of the Standard Output.
Allow'due south run the code and see.
1 of the dandy things about modest tools is their flexibility. If you write a program that does one thing actually well, chances are you lot will be able to use it in lots of contexts. If you create a plan that tin search for text inside a file, say, then chances are yous're going to find that plan useful in more one place.
For instance, think nearly your geo2json
tool. You created information technology to assist display cycling data, right? Just there's no reason you tin't use it for some other purpose...like investigating...the...
To come across how flexible our tool is, let's utilize it for a completely different problem. Instead of just displaying data on a map, let's try to use it for something a little more complex. Say you want to read in a whole set of GPS information like before, but instead of just displaying everything, let'south just display the information that falls within the Bermuda Rectangle.
That means y'all will display merely data that matches these weather:
((latitude > 26) && (breadth < 34)) ((longitude > -76) && (longitude < -64))
So where practise you demand to brainstorm?
Don't change the geo2json tool
Our geo2json
tool displays all of the information it's given. And so what should we practise? Should nosotros modify geo2json
then that it exports data and also checks the data?
Well, nosotros could , merely recollect, a small tool:
does one task and does it well
You don't really want to modify the geo2json
tool, because you want information technology to do just ane task. If y'all make the program do something more complex, yous'll crusade bug for your users who expect the tool to keep working in exactly the same way.
So if you don't want to change the geo2json tool, what should you lot do?
If you want to skip over the data that falls outside the Bermuda Rectangle, you should build a split up tool that does only that.
So, you'll accept two tools: a new bermuda
tool that filters out data that is exterior the Bermuda Rectangle, and then your original geo2json
tool that will catechumen the remaining data for the map.
This is how you'll connect the programs together:
By splitting the problem downward into ii tasks, you will be able to get out your geo2json
untouched. That will mean that its electric current users will nonetheless be able to use it. The question is:
How volition you connect your two tools together?
Connect your input and output with a pipe
You've already seen how to employ redirection to connect the Standard Input and the Standard Output of a program file. Merely now you'll connect the Standard Output of the bermuda
tool to the Standard Input of the geo2json
, like this:
The | symbol is a pipage that connects the Standard Output of one process to the Standard Input of another process.
That way, whenever the bermuda
tool sees a piece of data inside the Bermuda Rectangle, it will ship the information to its Standard Output. The pipe volition send that data from the Standard Output of the bermuda
tool to Standard Input of the geo2json
tool.
The operating system will handle the details of exactly how the pipe volition do this. All you accept to practise to get things running is consequence a command like this:
So now it'due south fourth dimension to build the bermuda
tool.
The bermuda
tool will piece of work in a very similar fashion to the geo2json
tool: it will read through a set of GPS data, line by line, so send data to the Standard Output.
But there will be two large differences. First, it won't send every piece of data to the Standard Output, just the lines that are within the Bermuda Rectangle. The second difference is that the bermuda
tool will always output data in the same CSV format used to shop GPS information.
This is what the pseudocode for the tool looks like:
Permit's plow the pseudocode into C.
Exercise this!
Only what if you lot want to output to more than 1 file?
We've looked at how to read information from i file and write to another file using redirection, but what if the program needs to do something a little more complex, like ship data to more one file?
Imagine y'all need to create another tool that will read a set of data from a file, and then split information technology into other files.
And then what's the trouble? You can't write to files, right? Trouble is, with redirection yous tin can write to but two files at virtually, one from the Standard Output and one from the Standard Fault. So what do you practice?
Scroll your own information streams
When a program runs, the operating system gives it three file data streams: the Standard Input, the Standard Output, and the Standard Error. But sometimes you demand to create other data streams on the fly.
The good news is that the operating organisation doesn't limit you to the ones yous are dealt when the plan starts. Y'all can coil your own equally the program runs.
Each information stream is represented by a pointer to a file, and yous can create a new data stream using the fopen()
role:
The fopen()
function takes ii parameters: a filename and a mode . The fashion can be westward
to write to a file, r
to read from a file, or a
to append data to the end of a file.
One time you've created a information stream, you tin can print to it using fprintf()
, just like before. But what if you need to read from a file? Well, at that place's as well an fscanf()
office to assist you lot exercise that too:
The mode is:
"westward" = write,
"r" = read, or
"a" = append.
fprintf(out_file, "Don't wear %s with %s", "red", "green"); fscanf(in_file, "%79[^\north]\n", sentence);
Finally, when yous're finished with a information stream, yous demand to close it . The truth is that all information streams are automatically closed when the program ends, simply information technology'south still a good idea to always close the data stream yourself:
fclose(in_file); fclose(out_file);
Let'south effort this out now.
The program runs, only...
If you compile and run the program with:
the programme will read the chilling.csv file and divide up the information, line by line, into three other files— ufos.csv , disappearances.csv , and other.csv .
That'southward great, simply what if a user wanted to split up the data differently? What if he wanted to search for different words or write to unlike files? Could he exercise that without needing to recompile the program each time?
There's more to primary()
The matter is, any program you lot write volition need to give the user the ability to modify the way it works. If it's a GUI plan, you will probably demand to give it preferences. And if it's a command-line plan, like our categorize
tool, it will need to give the user the power to laissez passer it command-line arguments :
Like whatsoever assortment in C, you demand some mode of knowing how long the array is. That'southward why the main()
function has ii parameters. The argc
value is a count of the number of elements in the array.
Command-line arguments really requite your program a lot more flexibility, and it's worth thinking about which things you desire your users to tweak at runtime. It will brand your plan a lot more than valuable to them.
OK, let'southward encounter how you lot can add together a little flexibility to the categorize program.
Sentry information technology!
The first argument contains the name of the programme as it was run by the user.
That means that the beginning proper command-line argument is argv[1]
.
Safety Check
Although at Head Showtime Labs we never make mistakes (coughing), it's important in real-world programs to bank check for problems when you lot open a file for reading or writing. Fortunately, if there'southward a problem opening a data stream, the fopen()
role will return the value 0. That means if you want to bank check for errors, you lot should change lawmaking like:
FILE *in = fopen("i_dont_exist.txt", "r");
to this:
FILE *in; if (!(in = fopen("dont_exist.txt", "r"))) { fprintf(stderr, "Can't open up the file.\due north"); render 1; }
Overheard at the Head First Pizzeria
Chances are, any program yous write is going to need options. If you lot create a chat plan, it's going to need preferences. If you write a game, the user will want to change the shape of the blood spots. And if you're writing a command-line tool, you are probably going to need to add together command-line options .
Command-line options are the footling switches you ofttimes see with command-line tools:
Permit the library do the work for you
Many programs use command-line options, and so at that place'south a special library function you can utilise to make dealing with them a fiddling easier. Information technology's chosen getopt()
, and each time you call it, it returns the side by side option information technology finds on the command line.
Let's see how it works. Imagine you have a program that can take a prepare of different options:
This plan needs one choice that will take a value ( -e
= engines) and another that is just on or off ( -a
= awesomeness). You can handle these options by calling getopt()
in a loop similar this:
Inside the loop, you lot accept a switch
argument to handle each of the valid options. The string ae:
tells the getopt()
function that a
and e
are valid options. The e
is followed by a colon to tell getopt()
that the -e
needs to be followed by an extra statement. getopt()
will point to that argument with the optarg
variable.
When the loop finishes, you tweak the argv
and argc
variables to skip past all of the options and get to the principal command-line arguments. That will make your argv
array look like this:
The Polite Guide to Standards
The unistd.h header is not actually office of the standard C library. Instead, information technology gives your programs access to some of the POSIX libraries. POSIX was an attempt to create a common set of functions for use across all popular operating systems.
Watch it!
After processing the arguments, the 0th argument will no longer be the plan name.
argv[0]
will instead point to the first command-line argument that follows the options .
Yous've got Chapter 3 under your belt, and now yous've added small tools to your toolbox. For a complete list of tooltips in the book, see Appendix B.
Source: https://www.oreilly.com/library/view/head-first-c/9781449335649/ch04.html
0 Response to "Read Json From Standard Input, Then Writes to Standard Output"
Postar um comentário