ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have been been baffled by this most of today and my searches on google have left me no wiser.
I amd trying to access various small conversion programs from a c program using a switch which calls another function. I believe this is called modulular programming. I have tried listing the a small conversion program in a header file but that did not work so I have tried listing the conversion program as a function in the header file but this does not work either and gcc gives me the following error:
Code:
cnvrt.c:27:4: error: a label can only be part of a statement and a declaration is not a statement
I am missing something and I don't know what it is. A heads up would be most appreciated. The header file and program follows:
Code:
#ifndef cnvrt_h
#define cnvrt_h
#include <stdio.h>
#include <stdlib.h>
int interest()
{
static float amount,rate,interest,daily,monthly;
printf ("\033[2J"); /* clears the screen */
printf ("\033[0;0H"); /* positions cursor at to left of screen */
printf("\n\t\t\t Interest Rate Utility\n\n");
printf ("\n\t\tThis module will calculate daily interest based");
printf ("\n\t\ton a given amount and a given interest rate.\n\n ");
// Get the amount to be finance
printf ("\n\t\tEnter the amount to be financed: ");
scanf ("%f",&amount);
// Get the interest rate
printf ("\n\t\tEnter the interest rate: ");
scanf ("%f",&rate);
interest=rate/100;
//printf ("\033[2J");
system ("clear"); // Use on linux with bash
printf ("\n\n\t\tThe amount to be financed is %.2f.\n",amount);
printf ("\t\tThe interest rate is %.2f%%.\n\n",interest*100);
daily=(amount*interest)/365;
printf ("\t\tThe daily interest would be $%.2f.\n",daily);
monthly=((amount*interest)/365)*30;
printf ("\t\tThe monthly, i.e. 30 days, interest would be $%.2f.\n\n",monthly);
return 0;
}
#endif
Code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "cnvrt.h"
int entry;
char input[BUFSIZ];
int main ()
{
printf ("\033[2J"); /* clears the screen */
printf ("\033[0;0H"); /* positions cursor at to left of screen */
printf("\n\t\t\t CONVERSION UTILITY\n\n");
printf("\t\tSelect a conversion module by entering the line number:\n\n");
printf("\t\t1 Calculate daily interest.\n");
printf("\t\t2 Convert Farenheit and Celsius temperatures.\n");
printf("\t\t3 Electrical calculations\n");
printf("\t\t4 Quit.");
printf("\n\t\t");
gets(input);
entry = atoi(input);
switch (entry)
{
case '1':
int interest (); /* go to the interest module */
break
;
case '2':
//temperatures(); /* go to conversions module */
break
;
case '3' :
printf ("\033[2J"); /* clears the screen */
printf ("\033[0;0H"); /* positions cursor at to left of screen */
printf("\n\n\t\t\tModule has not been included yet.");
break
;
case '4':
printf ("\033[2J"); /* clears the screen */
printf ("\033[0;0H"); /* positions cursor at to left of screen */
break
;
default:
printf ("\033[2J"); /* clears the screen */
printf ("\033[0;0H"); /* positions cursor at to left of screen */
break
;
}
return 0;
}
edit:
Since posting I have come across several websites where a solution is to use curly braces in the switch.
Code:
switch (entry)
{
case 1:
{
int interest ();
}
break
;
<snipped>
This allows me to compile the program without errors but when I run the program the function interest() does not run when I select " 1 " and the program exits (without any error messages. Perhaps that part is now correct but I'm still scratching my head over how to get interest() to run either from the header file or as a seperate program listed in the header file??
Last edited by justwantin; 03-24-2013 at 06:26 AM.
...
switch (entry)
{
case '1':
int interest (); /* go to the interest module */
...
The statement, as is, appears to the compiler as if you are declaring a function prototype. Since declarations are not possible within this simple case statement, the compiler throws an error. What you want is to remove the 'int' portion of the statement.
A couple of notes:
1. Had you enclosed the function prototype declaration associated with the case statement within curly brackets, then the compiler would be happy. However the goal of calling interest() would not be achieved, for the statement would still be a function prototype declaration.
2. It is customary to declare one or more function prototypes in a header file, and then implement the code in a source file. This is the gist of modular programming. The goal is to break up a large/complex code into smaller, more manageable, sets of code.
To link multiple source code files, you would do something like:
Code:
gcc Module1.c Module2.c Etc.c -o myapp
If typing a large statement is inconvenient, then consider looking into the use of a Makefile.
Last edited by dwhitney67; 03-24-2013 at 06:41 AM.
Thanks for your help. Its getting late here and I'm approaching silly mistakes time.
As standalone code both cnvrt.c and interest.c compile fine but its when I add #include "cnvrt.h" to the code I get two errors that make no sense to me. They are the same in both programs if I include cnvrt.h
Code:
gcc -Wall interest.c
interest.c: In function interest:
interest.c:6:1: error: expected =, ,, ;, asm or __attribute__ before { token
interest.c:36:1: error: expected { at end of input
interest.c:36:1: warning: control reaches end of non-void function [-Wreturn-type]
This indicates to me that my cnvrt.h is wrong but I have not found anything on the web today that made sense to me or matched what I'm trying to do which is call the function (program) interest.c from within cnvrt.c. Perhaps you or someone else could point me in the right direction. This is all I'm using
Header files are not normally used in the way you've used them. While it does work, the normal purpose of header files is to declare functions, global variables, #defined constants, define macros, and pull in other header files. I think the modularity you're trying to achieve should be done using standalone C source files which are individually compiled and then linked to constitute the final runtime binary object code. Convert your header file into a '.c' file, and compile it. Then compile the main module, and link it with the standalone object module.
Assuming a Linux-like development environment:
Code:
gcc -o convert.o -c convert.c
# Or, more simply:
make convert.o
# then...
gcc -o interest convert.o interest.c
You will have to declare the external function in your main module (a good purpose for a header file, but overkill if there are only two source files).
Header files are not normally used in the way you've used them.
After reading that I had a look at the source code on hand for a couple simple linux aps, dvbstream and the aps in dvb-tools. Some do and some don't.
Quote:
as said before, putting a function definition in a header file is really bad form
The two old C books I have, C in 24 hours and Unix and C by Cornes don't go into this nor do the C tutes I've looked at on the web. However I have found uni level lecture notes on the net that do use/teach with defining c programs as functions in headers, i.e. http://www.cs.bu.edu/teaching/c/separate-compilation/ or at least thats how I read them.
I this a vim/emacs issue in c programming? I've already come across one (it seems to me) for scanf/fgets although from what I've come across so far that one seems to be weighted towards fgets.
edit:
It just occurred to me that I might not be using the correct terminology. I am now declaring my programs as functions functions in a header file, then using gcc to compile each program separately and then gcc to link them. I'll wrap my head around makefiles after I get this right
Code:
#ifndef cnvrt_h
#define cnvrt_h
int interest ();
int temperatures ();
#endif
There you go! Kudos for seizing on -Wall.
In my example, no Makefile is required. make is smart enough to do the right thing all by itself in such simple cases.
The editor used to create the source files should be irrelevant. Perhaps it's use of syntax highlighting or other smart function is confusing you?
--- rod.
It just occurred to me that I might not be using the correct terminology. I am now declaring my programs as functions functions in a header file
Part of the mis-communication between you and bigearsbilly seems to come from that terminology issue of declaring vs. defining.
It is most common to declare functions in header files and define them in .c files.
There is also a terminology problem in your use of the word "programs" (in that quote). I'm just ignoring the whole "programs as functions" phrase to get the correct meaning of that sentence. I'm not sure whether you have some concept level misunderstanding behind that, or just terminology, or just a typo.
Another concept level difference is in the structure/naming of the header files. In the cs.bu link you provided and commonly in large projects, a header file is named the same as an individual source file contains the declarations needed by "clients" of that source file.
But in the example you provided, and commonly in very small projects, a header file named the same as a project contains all the declarations needed by all source files in the project.
You have a "convert" project using an "interest" module. In the common large project organization the interest function would be declared in interest.h. In the less common small project organization, it would be as you have shown with the interest function declared in the convert header.
Quote:
Originally Posted by bigearsbilly
a lot of idiots teach at Uni.
In general I agree with that (or think you understated it). But in context, no. I think an accurate quote from university didn't actually disagree with your position (the misuse of "define" to mean "declare" came from justwantin, not from the original). But I do disagree with that position.
Quote:
Originally Posted by bigearsbilly
If you did it on my team I would demote you to customer support.
Setting aside the management style issues implied by that, I just wanted to comment that real projects usually need some inline functions that are defined (not just declared) in header files.
There is also a terminology problem in your use of the word "programs" (in that quote). I'm just ignoring the whole "programs as functions" phrase to get the correct meaning of that sentence
in general
Yeah, that sentence out of context doesn't say much at all. What would be correct terminology? I actually think "program" in general doesn't always fit the usage. To me, something large, maybe complex, is a program but hello_world.c certainly wouldn't be. Don't know, never studied C formally nor discussed with anybody. I do allot of bash scripting. I have one bash script that I use for scheduling dvb-t to a hd. It is interactive and comprises 12 functions. You would understand if I said wrote a script for.... but to folks that visit my house it is a program that saves tv shows.
object module; what a C source files becomes after compiling it
executable; what 1 or more object files become after linking
header file
library; a collection of object modules in one file
I don't think there is any ambiguity in any of those terms. Just for good measure, throw in the term 'script' to describe any source file that is executed by an interpreter. Java seems to break all of these conventions.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.