LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
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, 09:52 PM   #1
jmgibson1981
Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 952

Rep: Reputation: 325Reputation: 325Reputation: 325Reputation: 325
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 09:54 PM.
 
Old 01-07-2023, 10:01 PM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 23,913

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

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

Rep: Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679Reputation: 1679
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, 11:16 PM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,683

Rep: Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008
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, 11:35 PM   #5
jmgibson1981
Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 952

Original Poster
Rep: Reputation: 325Reputation: 325Reputation: 325Reputation: 325
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, 04:59 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,594

Rep: Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629
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, 09:35 AM   #7
intestinal fortitude
LQ Newbie
 
Registered: Jan 2014
Posts: 12

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 09:36 AM.
 
Old 01-09-2023, 07:09 PM   #8
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 10,773

Rep: Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097Reputation: 5097
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, 07:41 PM   #9
jmgibson1981
Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 952

Original Poster
Rep: Reputation: 325Reputation: 325Reputation: 325Reputation: 325
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 07:58 PM.
 
Old 01-12-2023, 04:35 AM   #10
Owel
LQ Newbie
 
Registered: Nov 2021
Location: Europe
Distribution: Mainly MX Linux
Posts: 7

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 07:08 AM.
 
Old 01-16-2023, 07:25 PM   #11
rclark
Member
 
Registered: Jul 2008
Location: Montana USA
Distribution: KUbuntu, Fedora (KDE), PI OS
Posts: 265

Rep: Reputation: 76
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 07:33 PM.
 
1 members found this post helpful.
Old 01-16-2023, 09:00 PM   #12
jmgibson1981
Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 952

Original Poster
Rep: Reputation: 325Reputation: 325Reputation: 325Reputation: 325
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-17-2023, 12:20 AM   #13
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 7.7 (?), Centos 8.1
Posts: 18,145

Rep: Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672Reputation: 2672
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, 07:11 AM   #14
Owel
LQ Newbie
 
Registered: Nov 2021
Location: Europe
Distribution: Mainly MX Linux
Posts: 7

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 07:19 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 07:33 PM
Perl switch statement throwing error like Bad case statement (invalid case value?) kavil Programming 2 10-07-2010 05:50 AM
[SOLVED] Shell script for adding a statement in a file after a particular statement TheIndependentAquarius Programming 4 06-28-2010 04:07 AM
Problem with if statement in a find -exec statement romsieze Programming 2 10-02-2008 01:38 AM
Case statement with If statement cbo0485 Linux - Newbie 4 11-07-2007 09:05 PM

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

All times are GMT -5. The time now is 11:55 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