stderr
Posts: 2178
Joined: Sat Dec 01, 2012 11:29 pm

Re: Learning C in 5 minutes

Mon Mar 13, 2017 3:36 am

DavidS wrote:You see if you ignore these keywords you castrate the language.
Maybe he's saying that you might wait to deal with those things until you'd first got a toe hold on the Matterhorn of C?

LdB
Posts: 1242
Joined: Wed Dec 07, 2016 2:29 pm

Re: Learning C in 5 minutes

Mon Mar 13, 2017 4:50 am

I have some problems with your responses DavidS
DavidS wrote:volitile Used often, and needed when dealing with HW that can be changed by an external source.
Really it's not just hardware it's anywhere you want to guarantee the code does not get optimized away. It isn't just hardware it can be extern's (which you misunderstand below) that confuses the optimizer and you need to be able to correct. It actually isn't a compiler instruction at all its an optimizer instruction that is passed thru the compile phase.
DavidS wrote:volitile signed When working in systems that default to a unsigned char type for byte size data you are going to need to specify when you are using signed bytes.
Subtracting unsigned (1) from unsigned (0) gives you max unsigned type that is what the C standard says. Not on every C implementation and processor does max unsigned happen to equal negative 1. Most yes but it isn't a guarantee it just happens most processors at this point in time are twos complement. The same people you will find have no concept of what size_t is and it's use and importance.
DavidS wrote:extern As it is implicit in all cases where needed yes it can be ignored.
You can not ignore it anyone who wants to link assembler or external libraries to C has to have it. Again it's misunderstood by novices because it really isn't a compiler instruction it is a linker instruction that is passed thru the compiler. Anyone working on an embedded system pretty much has to have it as you can't link an assembler module to a c prototype without it. Nor can you link an external library to C without it.
DavidS wrote:extern const Arguable, though I agree that it can be ignored.
Again totally misunderstood by novices because it is a linker instruction used to define a read only entry. On systems with ROM it tells the linker to put the entry in the ROM area of memory. To not have the instruction means you would have to build the ROM block as a self stand module a complete nightmare. Telling the compiler something is read only might not be that interesting to you but the linker sure as hell wants to know if it has ROM.

My one thing I would add as mandatory teaching for C and C++ programming is there is a standard unit called <stdint.h> please use it rather than define your own types. The only exception to using the standard is when programming for an API where the API will dictate the types. It makes me want to kill people when I find u8, u16,u32 and the like .. what a waste of time and effort.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Learning C in 5 minutes

Mon Mar 13, 2017 8:14 am

stderr wrote:
DavidS wrote:You see if you ignore these keywords you castrate the language.
Maybe he's saying that you might wait to deal with those things until you'd first got a toe hold on the Matterhorn of C?
for a tutorial I fully agree. And if it's just for a "hello world" or perhaps read some GPIOs there would be no need to use all of the reserved keywords, all at once.
But step by step, the the language scope surely increases.

Anyway which keywords one could skip for the start, the trouble about C with the Pi is not if one tries to write a "hello world" or perhaps read some GPIOs. For that purpose and that level already millions of tutorials exist. The trouble starts if one wants to use HATs from Adafruit, but adafruit provides just Python support, or if one wants to use C with opencv (see my different topic), in that case also everything runs fine with Python whereas with C there are troubles where ever one looks.
There must be definitely a better support and better tutorials for C for advanced libs and devices, or otherwise it would not be worth while to start with learning C on the Pi at all. Only advanced users (perhaps professional programmers) with 30 years of C programming experience seem to have no problems, but tbh, I don't want to wait living and working 30 years as a professional C programmer before I was able to start using opencv or control Adafruit HATs.
IMO it was very wishful if even the Raspberry foundation started to support C/C++ as kind of a "2nd leg", and not just Python. But tbh, I meanwhile am very pessimistic about C for beginners on the Pi, to me it's quite frustrating. (Except for "hello world" or perhaps reading GPIOs, of course, but even for that purpose a ARM-core Arduino would be more suitable.) But anyway, it's finally not already the end of all days.

jahboater
Posts: 4696
Joined: Wed Feb 04, 2015 6:38 pm

Re: Learning C in 5 minutes

Mon Mar 13, 2017 9:02 am

I think these are at least partly personal preference! but

signed When working in systems that default to a unsigned char type for byte size data you are going to need to specify when you are using signed bytes.[/quote]
Yes, agreed, on the Pi ARM which cannot directly do twos-complement arithmetic on bytes - it only has 32-bit arithmetic and just uses the lsb. So ARM defaults to unsigned char.

register Used to be very helpful, until most compilers started ignoring it.
Still useful for ARM inline assembler - its the only way to force use of a particular register.
register const int sys asm( "r7" ) = SYS_ioctl;

enum Definitely ignorable.
Not essential but very useful. I use them all the time.

do For loops that are known to be executed at least one time this makes life a lot easier.
yes - and faster - one jump instead of two

const Arguable, though I agree that it can be ignored.
Definitely useful - it makes the code both safer and faster. Declare everything const that doesn't actually change.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Learning C in 5 minutes

Mon Mar 13, 2017 9:06 am

I think we can terminate the discussion about reserved keywords.
They exist, no question and no doubt about that, and if occuring in either tutorial, that depends just on the tutorial.
(I personally already have been using almost all of them one or the other time.)

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Tue Mar 21, 2017 10:16 pm

Ok, I said we would cover structures. Important in any serious discussion on C imo.

Here is an example of a structure:

struct customer_type
{
long customerid;
customername char[255];
phonenumber char[255];
comments[255];
} customer;

Just take a good look at how it works...instinctually I mean. You now know enough about variable types and C in general to be able to get the gist of it.

To explain, what it does is it defines a customized variable type that has subvariables. Wow, you can do that? Yes, one of the hidden powers of C and useful in a bunch of situations. In this example, it both stores it as a "type" (that can be used as a pattern to define other variables) as well as defining one variable "customer" of the type. The pattern, the type is stored in "customer_type" (hense the name).

How you access a structure's subvariables is thus:

customer.customerid = 100;

You use a period. Reference this example with the type above to figure out how it works.

You might have noticed how this example mirrors a "record" in a database (not an accident). Now what if you need more customers (since we only have one customer variable, "customer").. Remember how I said the pattern is stored as a new "type", you can now use this to define more customer records, err, variables.

struct customer_type customers[1000];

Might be useful for a program for a small boutique or barber shop. We now have an array of "customers" that we can store their information to. You know how to print things (printf) and to read in information from the keyboard (scanf) so you could, RIGHT NOW, write a C program that can save customer's information to an array (a structure array) even in a real life situation.

Autozone and other places still use this approach today to conduct business; these are called "legacy systems" and work just as well as they did decades ago.

(I would point out that it won't save them perminantly to disk and will disappear after you end the program, so maybe hold off on writting such a program until we cover how to save information to your hard drive and recall it when you run the program again.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Tue Mar 21, 2017 10:38 pm

Ok, now the first hard thing you'll encounter here. I'm all about easy but you gotta eat your peas now. You might want to take a break and approach this fresh as this is what really determines your proficiency at C, the principle that I'm going to talk about here, the grasp of it.

Referencing and Dereferencing

Every variable stores its value at a memory location somewhere in the computer (this should make sense), its "address" in memory. To get this address, you use an ampersand. For example, the following expression saves the address of variable b, in variable a :

a = &b;

To "dereference" (the inverse operation), you use an asterix. Dereferencing can be easily explained thus "If you know the address of a variable, you can retrieve the value stored in that variable." For example, the following expression saves the value of variable b, into variable c (we are assuming this appears right after the previous example in the program).

c = *a;

Read this little section, figuring out the logic, the reasoning, over and over again until you know you understand these two operations: referencing and dereferencing.

When you understand and can use this principle in your programming, this indicates a mastery of C language.

User avatar
Douglas6
Posts: 4770
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL

Re: Learning C in 5 minutes

Tue Mar 21, 2017 10:54 pm

woodystanford wrote: When you understand and can use this principle in your programming, this indicates a mastery of C language.
Cough, cough.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Wed Mar 22, 2017 12:07 am

stderr wrote:
DavidS wrote:You see if you ignore these keywords you castrate the language.
Maybe he's saying that you might wait to deal with those things until you'd first got a toe hold on the Matterhorn of C?
Exactly. Thank you, stderr.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Wed Mar 22, 2017 12:45 am

Been thinking for a bit...bear with me on this one, please.

With all the new technologies out there, a lot of the stuff discussed here seems...quaint. But imo there is a lot to be learned with just straight, traditional C language. I personally don't have a problem with interacting, through shell, in the printf/scanf kind of way, rather than something, let's say, like curses. There are some useful ways to use this in real-life programs that can (and do) enhance our daily lives.

I recently wrote a rather sophisticated program that calculates the correct values to build a rocket motor in just this way. It seems old-fashioned but I was pleased with the final result (and anticipating releasing it as shareware when compiled to a Win32 console program). It basically does what it says, and says what it does. You feed in the numbers, it crunches them and comes out with the output that fulfills the program requirements.

You will still have to learn some additional concepts (like functions that deal with the filesystem) before coming out with some useful programs in C but you have a foundation here. I would suggest trying some of these techniques to get comfortable with traditional C and imo writing programs that have application in real life are more interesting.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Fri Apr 07, 2017 1:01 am

A lot of you want to know how to read and write files. Here is a "loader" for that.

You just have to memorize 4 functions: fopen(), fwrite(), fread(), fclose().

UN*X tries to treat everything in terms of streams so that what you learn with one device (in this case the filesystem) you can apply it directly to other devices (this is called "abstraction"). With just these 4 functions you can save and retrieve just about anything to disk (or in the case of an R-Pi to the nonvolatile memory filesystem).

To use the functions, include <stdio.h> at the top of the program. In your main() function type the following:

FILE *fptr;
fptr=fopen("filename.txt","wb");

This opens a file stream that you can write to (what the "wb" code is for...write binary). Why are we covering binary files first? So when we cover text files it will be easier and you won't be afraid of binary files.

an fwrite works like this:

fwrite(pointer to data, size of the data element [in bytes] being written, number of elements, file pointer);

A pointer is just the address of the data (variables, structures, etc) so remember what you know about referencing and dereferencing. Explains why you'll see so many ampersands in the following examples. Here is an example that writes an integer, a char and a string to file.

fwrite(&a,2,1,fptr); fwrite(&b,1,1,fptr); fwrite(&s,sizeof(s),1,fptr);

You'll notice that argument 3 is always 1 in these examples. Why? You can probably figure out why the size of the data (in argument 2) is what it is. You can also use the reserved word sizeof(x) here as well.

Retrieving from file is the opposite process (remember to open in read mode with a "rb" code in the fopen):

fread(&a,2,1,fptr); fread(&b,1,1,fptr); fread(&s,sizeof(s),1,fptr);

Always remember to formally close each opened file with a fclose(fptr); when finished with them.

Here is an example program you can enter, compile and run.

Code: Select all

#include <stdio.h>

main()
{

	int a,a2; //integers
	char b,b2; //chars, or 1-byte characters
	char s[255]="This is just a test string"; //"string" 255 bytes long
	char s2[255];

	FILE *fp;

	a=1; b="D";

	fp=fopen("filename.txt","wb");
	fwrite(&a,2,1,fp);
	fwrite(&b,1,1,fp);
	fwrite(&s,sizeof(s),1,fp);
	fclose(fp);

	fp=fopen("filename.txt","rb");
	fread(&a2,2,1,fp);
	fread(&b2,1,1,fp);
	fread(&s2,sizeof(s2),1,fp);
	fclose(fp);

	printf("Saved/Retrieved Variables: %d, %c, %s\n\n",a2,b2,s2);

}

Last edited by woodystanford on Fri Apr 07, 2017 1:40 am, edited 2 times in total.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Fri Apr 07, 2017 1:28 am

OK, text files. This part is easy if you've mastered the material in the last post.

Binary, or data files, are great for some things, poor for others. A lot of times you'll want to use a text file.

Use the same fopen() and fclose() functions, but use fprintf() and fscanf() instead of fread() and fwrite(). Oh yeah and change the open code to "w" for "wb" for write and to "r" for "rb" ("b" is obviously for binary).

So to store the same information as from the previous example we can write it like this:

fprintf(fptr,"%d %c %s\n",a,b,s);

See why most people like to use text files instead, you basically just print to a file? If you want to know what all the printf/fprintf codes are just google "man fprintf". %d is for integer, %c will print a char, and %s a string.

To read it back:

fscanf(fptr,"%d %c %s",&a2,&b2,s);

"Oh these horrible little codes in C". There is a reason why the codes and the ampersands. When you call a function it copies the value of the variable to give to the function, so for printf() its straightforward.

However using scanf/fscanf the question becomes how do I get the information I need back. "Pass by reference" is the answer. If you pass the address of the variable you can write to the variable in the function and access it back in main().

Remember to formally close with fclose(fptr);

Code: Select all

#include <stdio.h>

main()
{

	int a,a2; //integers
	char b,b2; //chars, or 1-byte characters
	char s[255]="This is just a test string"; //"string" 255 bytes long
	char s2[255];

	FILE *fp;

	a=1; b="D";

	fp=fopen("filename.txt","w");
	fprintf(fptr,"%d %c %s\n",a,b,s);
	fclose(fp);

	fp=fopen("filename.txt","r");
	fscanf(fptr,"%d %c %s",&a2,&b2,s);
	fclose(fp);

	printf("Saved/Retrieved Variables: %d, %c, %s\n\n",a2,b2,s2);

}


User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Fri Apr 07, 2017 2:45 am

**** END OF LESSONS - you are now a traditional C programmer - congrats ( :D :D :D hands imaginary certificate kind of thing :D :D :D ) *****

Ok (enthusiastically), guess what you now have everything you need to start pumping out the...business apps.

Let's talk conceptually how this is done.

Let's start with an invoice (why...because I am me). You will notice that all invoices are of a certain structure.

Code: Select all

Date: 1/1/2017                   From:	<Your Business Name>
                                        <MAddress1>
InvoiceID: 1234                         <MCity>, <MState> <MZip>

To:
<Their Business Name>            Terms: Net 30
<Maddress1>
<MCity>, <MState> <MZip>

Date     Description                    Unit    Qnty    SubTotal
                                        Price
----------------------------------------------------------------
12/12/17 Service X: changed some things $25.00  1.00    $25.00
         on their web site. 	
	
12/12/17 Item X: nice 8GB Sandisk SD    $18.99  1.00    $18.99
	 Card (free delivered).			

12/12/17 Sales Tax on above items       $2.76   1.00    $2.76
----------------------------------------------------------------

                                         Grand Total:   $46.75
							========

     Thank you so much for your business!
This is a template for an invoice. You invoice people to get money off of them; you perform the service or give them the sold item. You have receipts for sales made directly, but if you do business with businesses (also called B2B aka Business-to-Business) then you will have to invoice them.

How you would code this in C is like this:

Code: Select all


printf("Date: %d/%d/%d                   From:	%s\n",dm1,dd1,dy1,bname);
printf("                                        %s\n",maddress1);
printf("InvoiceID: %ld                         %s, %s %s\n",iid,mcity,mstate,mzip);
printf("\n");
printf("To:\n");
printf("%s            Terms: %s\n",cbname);
printf("%s\n",cmaddress1);
printf("%s, %s %s\n",cmcity,cmstate,cmzip);
printf("\n");
printf("Date     Description                    Unit    Qnty    SubTotal\n");
printf("                                        Price\n");
printf("----------------------------------------------------------------\n");

for (a=0;a<1;a++)
{
	printf("%d/%d/%d %s $%.2f  %.2f    $%.2f\n",ldm[a],ldd[a],ldy[a],ls[a],lup[a],lqty[a],lup[a]*lqty[a]);
	printf("         %s\n");

	rtotal+=lup[a]*lqnty[a];
}

gtotal=rtotal;

printf("----------------------------------------------------------------\n");
printf("\n");
printf("                                         Grand Total:   $%.2f\n",gtotal);
printf("							========\n");
printf("\n");
printf("     Thank you so much for your business!\n");

The C code supplied will print the populated invoice to the screen. You could just cut and paste the code again with fprintf's to a text file and print it from there (to a dot-matrix or even a modern laser/inkjet). When you do it this way, get the letterhead applied to a box of paper at a print shop.

A trick I do to get the letterhead on automatically is I use this same template but written in HTML (all you do is the fprintf thing to a *.html file and include the necessary hand-coded tags like <b> and <img>). In VB.NET I would just load the HTML from file (making sure that all the images were in the same directory so the browser control can find it) and invoke its print method.

A nice modern-looking way to do the same invoice without the added cost and fuss of having to go to the printers to apply the letter head. And all done from your little R-Pi box that you plug in with your cell phone charger in that $10 box you got from Adafruit or somewhere. A lot better than that old Pentium box that does the same thing (and is a nightmare to keep up).

Don't like terminal access (like with the old style terminal...expensive), just buy a bunch of (used) laptops with Windows 10 preloaded and then putty into your "host" (just make the R-Pi the "hotspot" and connect to it as you would a broadband router...OR if you have a broadband router, guess what an R-Pi will just connect to the LAN via its TCP-IP stack and automatically DHCP so you can do this with minimum fuss.)

Just find its IP address and type it into putty. Put putty on a desktop icon and at the start of the business day just double-click it. Like I was saying Autozone, Check and a bunch of other places still use this technology successfully.
Last edited by woodystanford on Fri Apr 07, 2017 3:51 am, edited 1 time in total.

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Fri Apr 07, 2017 3:49 am

OK, I can tell that a lot of you are like white-hot on these R-Pi C....business apps. lol jk

While not part of C proper, let's cover some basic database theory to give you some ideas.

From a database paradigm, everything is stored in "tables". These 2-dimensional arrays of information are the core of even this big systems. In C you might say something like this:

char [10000][10][255]; //possibly the simplest database TABLE you can have
//10,000 RECORDS with 10 FIELDS each, with each field being a string 255 bytes long

W-o-w that was easy huh? However not very practical in real-life. However if we do this:

struct vendor_type
{
long vendorid;

char vname[255]; //vendor company name
char vpadress1[60]; //vendor physical address
char vpcity[35];
char vpstate[3];
char vpzip[15];

char vpadress1[60]; //vendor mailing address
char vpcity[35];
char vpstate[3];
char vpzip[15];

char vphone1[20]; //other vendor info
char vfax[20];
char vemail[100];

long created; <<creation timestamp, use seconds after EPOCH
int active;
} vendors[1000];


Now we have a TABLE that we can do something with ( I know its just a structure array, but please bear with me on this one.

Primary and Foreign Keys

OK, to do what I'm going to talk about we need to talk a little about "primary" and "foreign" keys. Keys (more precisely, primary keys) are just numeric tags that uniquely identify a record (aka a row, the base unit of information in the database). They become useful as you link the information in one table to information in another table. Cool with that idea?

A foreign key is a link in a table to the primary key in another table. Remember this.

For example, whenever you receive a shipment from a vendor, the vendorid will appear in the rshipment TABLE put in a foreign key FIELD, vendorid. Structurally it might look like something like this:

struct rshipment_type
{
long rdid; //Received Shipment ID
long vendorid; //vendor the shipment came from
int employeeid; //id of employee who processed shipment
.
.
.


Here we have the PRIMARY KEY for the rshipment TABLE, rdid, but we also have the foreign keys to the tables Vendors and Employees that are populated with the correct number to uniquly identify the vendor involved and the processing employee. It should make sense that the reason why you do this is so you can look up the required information without duplicating information over and over again.

The novice's first instinct is to use a char[255] field and then put the employee's name in there every time. He then might get more sophisticated and learn that the employee's initials will suffice, however he hits a road block when his boss asks him if he can recall the employee's phone number or mailing address based on who processed shipment X.

Then he realizes that he should have just taken what Woody said on faith and just did it the right way from the get go. (However the scenic route was fun wasn't it?)

Let's look at a generic "boilerplate" set of tables that describes a minimalist business app:

customers
employees
vendors (or you could use "suppliers" here, I guess)
accounts_receivable
accounts_payable
invoices <<you want to hard copy all generated invoices to a literal table, trust me on this
purchase_orders
mybusiness <<where you put your current business name, address and stuff


I'm forgetting a lot of tables here so I'll just come back and edit when I figure out the actual minimal set to completely describe a small-to-medium sized business. However you can see that the invoices table would have the primary key (always a long integer btw jk) InvoiceID, but also foreign keys in it that specified which customer (ie. CustomerID) you sent the invoice too, and maybe which employee handled the fulfillment of it (ie. EmployeeID).

That way you can link to that information as you need it. Those that have used ACCESS or whatever have already been exposed to a lot of these principles, but I just wanted you to see how you can code in C with those same principles to build the next Google or Apache or SAAP app.

Can you do a fairly sophisticated business app just the old fashioned way with text files and figuring things out? Of course....its America. We put up with a lot of mischief here...kidding. I'm just saying my way is the RIGHT way is all (Halo).

User avatar
woodystanford
Posts: 122
Joined: Sun Feb 19, 2017 8:17 am

Re: Learning C in 5 minutes

Fri Apr 07, 2017 5:12 am

OK, so what's the power with this TABLE approach?

Make a function called savetables() and loadtables() (for now, horribly inefficent and limited by the R-Pi's RAM) boom there you go, you have the ability to save and load you data. Maybe break it out by saving and loading by table to make it a little more efficient.

Here is the code to save a TABLE:

you just go:

fwrite(num_customers,2,1,fptr); //assumes num_customers is an integer
fwrite(customers,sizeof(customer_type),num_customers,fptr);


(notice the 3rd argument isn't 1 this time, why they have this argument, so you can save arrays of things; also note that to save on drive space that you can just save as many rows -RECORDS - as you have populated and maybe just design the data file such that the first 2 bytes hang onto the number of rows saved).

"Seriously, you can save that whole structure array with just that one line?" Yep :D

and to load a table:

fread(customers,sizeof(customer_type),num_customers,fptr);

Real easy to save/load the entire "database"; just keep calling fwrite for each table or "structure array" in the "database".

OK, so what's the real power of this approach. I'll show you. Your boss asks you "Hey I need the contact phone number for the employee responsible to receiving shipment X.":

Your C code might go something like this:

strcpy(contact_phone, GetFieldFromTable("employees","ephone1", GetEmployeeIDFromRSID(tmp_RSID));

(strcpy() copies a string in arg 2 to arg 1 btw. If you see a function here you don't know just google "man functionname" and figure out how it works)

Its now in variable contact_phone. I mean you would have to code functions GetFieldFromTable() and GetEmployeeIDFromRSID() but the information is THERE in the form of primary/foreign key linkages to be able to retrieve it.

Note that you could have coded it this way:

tmp_eid=strol(GetFieldFromTable(s,"rshipment","employeeid",tmp_rsid));
GetFieldFromTable(contact_phone,"employees","ephone1", tmp_eid);


but you can code "helper" functions for commonly used lookups; for example all GetEmployeeIDFromRSID() is is just:

long GetEmployeeIDFromRSID(long rsid)
{
char eid[20];
GetFieldFromTable(eid,"employees","employeeid",rsid);
return strol(eid); //converts string to its numberic value and returns it
}


You can chain these functions together to give you the one-to-one, the one-to-many, the many-to-many RELATIONSHIPS that exist in a true relational database. Let's say you need the name of the area code of the employee responsible for processing shipment x. Just chain them together.

User avatar
PeterO
Posts: 5032
Joined: Sun Jul 22, 2012 4:14 pm

Re: Learning C in 5 minutes

Fri Apr 07, 2017 7:56 am

woodystanford wrote:

Code: Select all

#include <stdio.h>

main()
{

	int a,a2; //integers
	char b,b2; //chars, or 1-byte characters
	char s[255]="This is just a test string"; //"string" 255 bytes long
	char s2[255];

	FILE *fp;

	a=1; b="D";

	fp=fopen("filename.txt","wb");
	fwrite(&a,2,1,fp);
	fwrite(&b,1,1,fp);
	fwrite(&s,sizeof(s),1,fp);
	fclose(fp);

	fp=fopen("filename.txt","rb");
	fread(&a2,2,1,fp);
	fread(&b2,1,1,fp);
	fread(&s2,sizeof(s2),1,fp);
	fclose(fp);

	printf("Saved/Retrieved Variables: %d, %c, %s\n\n",a2,b2,s2);

}

You still can't be bothered to check your code before posting it can you ?

Code: Select all

 gcc  -Wall -Wextra wd1.c 
wd1.c:3:1: warning: return type defaults to ‘int’ [-Wreturn-type]
 main()
 ^
wd1.c: In function ‘main’:
wd1.c:13:10: warning: assignment makes integer from pointer without a cast [enabled by default]
    a=1; b="D";
          ^
wd1.c:29:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
Last edited by PeterO on Sun Apr 09, 2017 6:04 pm, edited 1 time in total.
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
PeterO
Posts: 5032
Joined: Sun Jul 22, 2012 4:14 pm

Re: Learning C in 5 minutes

Fri Apr 07, 2017 8:00 am

woodystanford wrote:

Code: Select all

#include <stdio.h>

main()
{

	int a,a2; //integers
	char b,b2; //chars, or 1-byte characters
	char s[255]="This is just a test string"; //"string" 255 bytes long
	char s2[255];

	FILE *fp;

	a=1; b="D";

	fp=fopen("filename.txt","w");
	fprintf(fptr,"%d %c %s\n",a,b,s);
	fclose(fp);

	fp=fopen("filename.txt","r");
	fscanf(fptr,"%d %c %s",&a2,&b2,s);
	fclose(fp);

	printf("Saved/Retrieved Variables: %d, %c, %s\n\n",a2,b2,s2);

}

More code that doesn't even compile....

Code: Select all

wb2.c:3:1: warning: return type defaults to ‘int’ [-Wreturn-type]
 main()
 ^
wb2.c: In function ‘main’:
wb2.c:13:10: warning: assignment makes integer from pointer without a cast [enabled by default]
    a=1; b="D";
          ^
wb2.c:16:12: error: ‘fptr’ undeclared (first use in this function)
    fprintf(fptr,"%d %c %s\n",a,b,s);
            ^
wb2.c:16:12: note: each undeclared identifier is reported only once for each function it appears in
wb2.c:25:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

jahboater
Posts: 4696
Joined: Wed Feb 04, 2015 6:38 pm

Re: Learning C in 5 minutes

Fri Apr 07, 2017 8:15 am

Its always worth checking the return from file handling functions:

Code: Select all

if( (fp = fopen("filename.txt","rb")) == NULL )
    ... fail gracefully

User avatar
Paeryn
Posts: 2680
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Learning C in 5 minutes

Fri Apr 07, 2017 10:20 am

woodystanford wrote:

Code: Select all

	int a,a2; //integers
...
	fwrite(&a,2,1,fp);
...
	fread(&a2,2,1,fp);
Definitely not even checked that the output is correct...
You read and write a and a2 which are defined as int but you only read and write the first 2 bytes... An int is generally 4 bytes on 32-bit systems.

Code: Select all

  fwrite(&a, sizeof a, 1, fp);
  fread(&a2, sizeof a2, 1, fp);
She who travels light — forgot something.

jahboater
Posts: 4696
Joined: Wed Feb 04, 2015 6:38 pm

Re: Learning C in 5 minutes

Fri Apr 07, 2017 11:33 am

Another good reason to use <stdint.h>, you are constantly aware how big your integer variables actually are.

User avatar
scruss
Posts: 2497
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Learning C in 5 minutes

Fri Apr 07, 2017 12:34 pm

[quote="woodystanford"]

Code: Select all

printf("Date: %d/%d/%d                   From:	%s\n",dm1,dd1,dy1,bname);
printf("                                        %s\n",maddress1);
printf("InvoiceID: %ld                         %s, %s %s\n",iid,mcity,mstate,mzip);
This doesn't work for 90% of the world's addresses. Frank da Cruz's glorious (and still maintained after 30+ years) “FRANK'S COMPULSIVE GUIDE TO POSTAL ADDRESSES” tells just a small part of the story.

I also feel deeply, deeply sorry for anyone writing invoicing code in C.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

User avatar
DougieLawson
Posts: 36179
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: Learning C in 5 minutes

Fri Apr 07, 2017 2:15 pm

scruss wrote:]
This doesn't work for 90% of the world's addresses. Frank da Cruz's glorious (and still maintained after 30+ years) “FRANK'S COMPULSIVE GUIDE TO POSTAL ADDRESSES” tells just a small part of the story.

I also feel deeply, deeply sorry for anyone writing invoicing code in C.
We win the game http://www.columbia.edu/~fdc/postal/#uk here in Blighty "Where to find the most confusing addresses on earth..."
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

User avatar
scruss
Posts: 2497
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Learning C in 5 minutes

Sat Apr 08, 2017 2:51 am

Although they've got a lot shorter in the last few years. My sister's place — in a Yorkshire village so small it doesn't have a pub — used to be about 8 lines. Now it's four.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

stderr
Posts: 2178
Joined: Sat Dec 01, 2012 11:29 pm

Re: Learning C in 5 minutes

Sat Apr 08, 2017 3:04 am

PeterO wrote:More code that doesn't even compile....
Also, we are well past five minutes.

1dot0
Posts: 430
Joined: Mon Nov 28, 2016 12:31 pm

Re: Learning C in 5 minutes

Sun Apr 09, 2017 5:38 pm

as I have already stated in another topic about " easy to write clean code":
I fully agree, for a quick and dirty code solution about a rough source code idea it should at least compile without any issues, some warnings may be acceptable (-Wall)
Instead, for a tutorial to beginners, either code is expected to compile super clean, even without any a warning (-Wall). Anything else would be extremely confusing to beginners and so would be absolutely inacceptable.

The gcc setup has to be the same as for the current Raspbian Jessie release, latest apt update + upgrade. Unfortunately gcc (g++) is still no 6.x (C++11) on te current Jessie, but that has to be considered as well for a tutorial to C/C++ targeting Raspberry Pi users.

Return to “C/C++”