LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-07-2023, 08:52 PM   #1
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,153

Rep: Reputation: 394Reputation: 394Reputation: 394Reputation: 394
C if statement not working properly.


Code:
	char helper[4];
	sscanf(argv[1],"%s",&helper);
	char helptest[4] = "help";
	printf("%s\n", helptest);
	exit(0);
	int compare = strcmp(helper, helptest);
	if ( compare = 0 ) {
		print_help();
	} else if ( argc != 4 ) {
		printf ("usage : %s num | op | num\n", argv[0]);
		return 0;
	}
I was adding this to my c to print a help page if needed.

I added the prinf and exit(0) to test the output because the if else wasn't working. as it turns out the helptest is coming back with this result

Code:
helphelp
So clearly not matching the test rules. Why is that and or how can I fix that?

Of course changing the compare to check for a 1 instead of a 0 makes it only print the help and never do anything beyond that. Stuck well.

entire source

Code:
/* 
 * author - Jason Gibson
 * version - 1.01
 * a simple non decimal point calculator
 * 
 * this source code is licensed under the GPLv3 or any previous version.
 * a copy of this license is found in the proper git location or can be found 
 * online at https://www.gnu.org/licenses/gpl-3.0.en.html 
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// functions declaration

int print_func(int solution);
int print_help();
int math_func(int num1, char op, int num2);

// main funtion

int main( int argc, char *argv[]) {
	// exit if wrong number of arguements supplied
/*
	if ( argc != 4 ) {
		printf ("usage : %s num | op | num\n", argv[0]);
		return 0;
	}
*/
	char helper[4];
	sscanf(argv[1],"%s",&helper);
	char helptest[4] = "help";
	printf("%s\n", helptest);
	exit(0);
	int compare = strcmp(helper, helptest);
	if ( compare = 0 ) {
		print_help();
	} else if ( argc != 4 ) {
		printf ("usage : %s num | op | num\n", argv[0]);
		return 0;
	}
	int num1, num2, ret;
	char op;
	sscanf(argv[1],"%i",&num1);
	sscanf(argv[3],"%i",&num2);
	sscanf(argv[2],"%c",&op);
	// send variables to math_function
	ret = math_func(num1, op, num2);
}

// print function

int print_func(int solution) { // print answer as needed
	printf("answer is %i\n", solution);
	return 0;
}

int print_help() {
	printf("This program does simple non decimal point math\n");
	printf("Pattern is Number Operator Number\n");
	printf("Examples:\n");
	printf("Addition = 4 + 4\n");
	printf("Subtraction = 4 - 4\n");
	printf("Multiplication = 4 \"*\" 4\n");
	printf(": you need to quote the operator for multiplication with\n");
	printf("a typical shell\n");
	printf("Division = 4 / 2\n");
	printf(": it will calulate a remainder as needed\n");
	exit(0);
}

// math function

int math_func(int num1, char op, int num2) {
	int solution;
	int math_ret;
	switch (op) {
		case '+': // addition working
			solution = num1 + num2;
			break;
		case '-': // subtraction working
			solution = num1 - num2;
			break;
		case '*': // need to quote * from the shell due to expansion - working
			solution = num1 * num2;
			break;
		case '/': // division working
			if ( num1 == 0 || num2 == 0 ) { // prevent divide by 0
				printf("you cannot divide by zero!\n");
				exit(1);
			} else if ( num1 % num2 != 0 ) { // run solution if odd remainder
				int remainder = num1 % num2;
				solution = num1 / num2;
				printf("answer is %i with a remainder of %i\n", solution, remainder);
				return 0;
			}
			solution = num1 / num2; // solution if no remainder
			break;
	}
	math_ret = print_func(solution);
	return 0;
}

Last edited by jmgibson1981; 01-07-2023 at 08:54 PM.
 
Old 01-07-2023, 09:01 PM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,789

Rep: Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950Reputation: 5950
The correct syntax is...

if ( compare == 0 ) {
 
Old 01-07-2023, 09:58 PM   #3
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,882
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Code:
	if (argc>=2 && strcasecmp(argv[0], "help")==0) {
		print_help();
                return 0;
	} else if ( argc != 4 ) {
		printf ("usage : %s num | op | num\n", argv[0]);
		return 0;
	}
 
Old 01-07-2023, 10:16 PM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
FYI, if you add -Wall to your compiler flags:

Code:
lq-calc.c: In function 'main':
lq-calc.c:27:7: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
   27 |  if ( compare = 0 ) {
      |       ^~~~~~~
 
Old 01-07-2023, 10:35 PM   #5
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,153

Original Poster
Rep: Reputation: 394Reputation: 394Reputation: 394Reputation: 394
Thank you. I was able to simplify it just now down to just this from what I started with.

Code:
	if ( strcmp(argv[1],"help") == 0 ) {
		print_help();
	}

int print_help() {
	printf("This program does simple non decimal point math\n");
	printf("Pattern is Number Operator Number\n");
	printf("Examples:\n");
	printf("Addition = 4 + 4\n");
	printf("Subtraction = 4 - 4\n");
	printf("Multiplication = 4 \"*\" 4\n");
	printf(": you need to quote the operator for multiplication with\n");
	printf("a typical shell\n");
	printf("Division = 4 / 2\n");
	printf(": it will calulate a remainder as needed\n");
	exit(0);
}
 
Old 01-08-2023, 03:59 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,047

Rep: Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348Reputation: 7348
The C if statement is working properly, otherwise the language could not be used at all. (That is just nonsense).
The -Wall (and other compiler flags) are used to detect common mistakes like this one (= is assignment, == is comparator).
 
Old 01-08-2023, 08:35 AM   #7
intestinal fortitude
LQ Newbie
 
Registered: Jan 2014
Posts: 13

Rep: Reputation: Disabled
This is more of an FYI since the updated code removed this. Your original code had this:
Code:
char helptest[4] = "help";
This is almost always wrong because it creates a byte-array without the string termination character ('\0'). It should be:
Code:
char helptest[5] = "help";
The extra byte is necessary for the string-termination byte. Or, even easier:
Code:
char helptest[] = "help";
The C compiler will determine the size for you.

Last edited by intestinal fortitude; 01-08-2023 at 08:36 AM.
 
Old 01-09-2023, 06:09 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,256

Rep: Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338Reputation: 5338
The usual recommended way to do that is:
Code:
const char *helptest = "help";
The string literal is a stored as a constant in memory, so you want the array holding it or the pointer pointing to it to be constant too.
 
Old 01-09-2023, 06:41 PM   #9
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,153

Original Poster
Rep: Reputation: 394Reputation: 394Reputation: 394Reputation: 394
Thank you. Makes more sense. I used many of your suggestions in the last day or so as I keep making and learning.

In this case though I found a slightly less complicated way to go about it though. I open my main with this.

Code:
	// run help output if needed
	if (argc != 4) {
		print_help();
		exit(1);
	}
and I just modify per program for expected arguements. Between this and my existing error checks for proper input I think it's set. final version my in gitlab for c in sig. jointcalc.c is where I combined both my float and int calcs into one.

Last edited by jmgibson1981; 01-09-2023 at 06:58 PM.
 
Old 01-12-2023, 03:35 AM   #10
Owel
LQ Newbie
 
Registered: Nov 2021
Location: Europe
Distribution: Slackware Linux mainly
Posts: 13

Rep: Reputation: Disabled
Quote:
Originally Posted by jmgibson1981 View Post
Thank you. I was able to simplify it just now down to just this from what I started with.

Code:
	if ( strcmp(argv[1],"help") == 0 ) {
		print_help();
	}

	exit(0);
}
It is better not to call functions this way. This piece of code does not simplify, but complicates the understanding of the program.
Use a separate variable, where the result of the comparison is saved, and then check the value of the variable. For example like this:

Code:
cmp = strcmp(argv[1], "help");
if (cmp == 0)
/* your code */

Last edited by Owel; 01-17-2023 at 06:08 AM.
 
Old 01-16-2023, 06:25 PM   #11
rclark
Member
 
Registered: Jul 2008
Location: Montana USA
Distribution: KUbuntu, Fedora (KDE), PI OS
Posts: 496

Rep: Reputation: 182Reputation: 182
And I don't know who started the crazy '{' placement idea but much more readable by blocking instead:

Code:
int main(int argc, char *argv[]) 
   {
   if ((argc >= 2) && (strcasecmp(argv[0], "help") == 0)) 
      {
      print_help();
      return 0;
      } 
   else if (argc != 4) 
      {
      printf("usage : %s num | op | num\n", argv[0]);
      return 0;
      }
   // 'else' here is not needed, but was in original code.
   return(1);
   }
We tried all different ways back in the 80s and by the 90s the above form is what we settled on as a company when writing C/C++ code. Very easy to see what brace is associated, what will be executed, and is much easier to read by the next person that comes along.

We didn't (and I still don't) use tabs (just spaces) either as some editors had tabs defined differently which screwed up the code listings.

We never relied on precedence either but use parenthesis liberally. No second guessing the meaning of statements.

Anyway just my two cents .

BTW, My background was real time programming of SCADA and Automation of Hydro/Substation/Comm applications before moving to maintaining Energy Management Systems with a utility. I majored in Computer Science Applied back then....

Last edited by rclark; 01-16-2023 at 06:33 PM.
 
1 members found this post helpful.
Old 01-16-2023, 08:00 PM   #12
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,153

Original Poster
Rep: Reputation: 394Reputation: 394Reputation: 394Reputation: 394
You are correct. I haven't posted because I've had a lot going on but I did pick up a sale at Udemy. Got Beginner C, Advanced C, and something else. Can't recall. But well worth it thus far. Learning quick. Just don't have as much time the last few days.

That was one of the things they mentioned in one of the lecture things. The braces should be like that. I guess the way I was doing it is more consistent with JavaScript. At least in this guys viewpoint for his class or whatever this thing is.

Code:
int main()
{
  return 0;
}
 
Old 01-16-2023, 11:20 PM   #13
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,369

Rep: Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753Reputation: 2753
Yep, definitely line parentheses up vertically and never rely on knowing(!) precedence - use brackets/parentheses as needed.

Some precedence rules aren't what you expect, and even if you can remember them all and not make a mistake the next guy to look at your code will not and will curse you
BTDT and got multiple T-shirts...
 
Old 01-17-2023, 06:11 AM   #14
Owel
LQ Newbie
 
Registered: Nov 2021
Location: Europe
Distribution: Slackware Linux mainly
Posts: 13

Rep: Reputation: Disabled
I use to place brackets like this:

Code:
int main(int argc, char *argv[]) 
{
   if ((argc >= 2) && (strcasecmp(argv[0], "help") == 0)) {
      print_help();
      return 0;
   } 
   else if (argc != 4) {
      printf("usage : %s num | op | num\n", argv[0]);
      return 0;
   }
   return(1);
}

Last edited by Owel; 01-17-2023 at 06:19 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Running mysql from ssh & query statement has a Text Header in the SELECT statement? djlerman Linux - Server 6 11-19-2013 06:33 PM
Perl switch statement throwing error like Bad case statement (invalid case value?) kavil Programming 2 10-07-2010 04:50 AM
[SOLVED] Shell script for adding a statement in a file after a particular statement Aquarius_Girl Programming 4 06-28-2010 03:07 AM
Problem with if statement in a find -exec statement romsieze Programming 2 10-02-2008 12:38 AM
Case statement with If statement cbo0485 Linux - Newbie 4 11-07-2007 08:05 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:38 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration