making a while loop with scanf inside to call functions - c

I'm trying to do an assignment for a class where we create a while loop using the scanf function. Basically the program is a calculator where the user should be able to type things like add 20 and my main function should be able to call up the functions from another .c then continue on in the loop.
However this is first time I am programming and I have no idea how to format or begin a loop that scans the input from the user, calls the appropriate mathematical function, applies it, then continues on in the loop.
Here's what I have done for the loop so far, which surprisingly, didn't work:
#include "calc.h"
#include "stdheader.h"
int main(int argc, char ** argv){
int c;
char token[81];
while(c != EOF){
if (scanf("%s", token) == "clear"){
calc.clear();
}else{
}
}
return 0;
}
and here is a sample of the functions that it should be able to call up (or what I have for them at least)
int local;
local = 0;
void clear(void){
local = 0;
printf("\n%d", local);
}
void add(int c){
local = local + c;
printf("\n%d", local);
}

In C, strings (and arrays more generally) are not first-class data types and cannot be compared by ==. Moreover scanf() does not return a string in any case - you should read the documentation carefully.
Change:
if (scanf("%s", token) == "clear")
to:
scanf( "%s", token ) ;
if( strcmp( token, "clear" )
Additionally the test c == EOF is dangerous because c is not initialised.
int c = 0 ;

My observation:
comparing string with == is not a suggested one. Instead try to use strcmp
scanf() returns only integer, you are comparing it to clear in if (scanf("%s", token) == "clear")
changing code like
if(scanf("%5s", token) == 1 && strcmp("clear",token) == 0)
Also what is the initial value of int c = ? without this how can you compare here while(c != EOF)

You need to look at the details of how scanf() works.
Here is a good reference.
scanf() returns the number of tokens read, an int not a string. You can't compare strings with == anyway. To compare strings you would have to use strcmp() from the string.h library.
You don't need to prepend calc on the front of your clear() function.
There are several errors here, you're best path forward might be to try something simpler first.

However this is my first time programming and I have no idea how to format or begin a loop that scans the input from the user, calls the appropriate mathematical function, applies it, then continues on in the loop.
When you want to solve a problem that is more complex than you think that you can solve it break it up in sub-problems. First design the user interface. What should the user enter to communicate with the program.
When you have a plan integrate the features that you need:
parsing user input
formatting of output
number processing (some arithmetic in your example).

A completely different approach to solve your problem.
Have array of function pointers.
typedef int (*func) (int,int);
func a[] = {add,sub,div,mul};
Have your UI like
printf("0 - add , 1- sub, 2 - div, 3 - mul\n");
scanf("%d",&op);
printf("Enter 2 numbers\n");
scanf("%d %d",&var1,&var2);
Now have
a[op](var1,var2);
Define your functions accordingly . For eg
int add(int x,int y)
{
return x+y ;
}
and so on.

Related

Character C-function, misconception on its behaviour

An exercise asked to write a function that:
reads a sequence of alphabetic characters (without memorizing the sequence) that ends only when the users enters '\n'.
returns 1 if the number of capitalized letters went beyond the lower ones of at most an integer m, entered by the user, or 0 else.
I tried with the following code:
#include<stdio.h>
int read(int p,char c)
{
int M=0,m=0,d;
char A,Z,a,z;
while(c != '\n')
{
if(A<=c<=Z)
{
M++;
}
else if(a<=c<=z)
{
m++;
}
scanf("%c",&c);
}
if(M-m>0)
d=(m-M);
else
d=0;
if(d==0)
return 0;
else if (d<=p)
return 1;
}
int main()
{
int a,h;
char k;
scanf("%d", &h);
scanf("%c", &k);
a=read(h,k);
printf("%d\n",a);
return 0;
}
At this point, trying to execute the program with the gcc command, i noticed that the program was taking just the integer, let's say 2, and gave back 0 as if it entered in the function without taking the second scan on the character.
Besides the formal misconception and errors about the program and c function that i'm glad you rectify,
I was trying to understand, because as they say i'm trying to be self-taught, how scanf function and function work in general, when and to who priority is given.
For example in function read it's not clear to me when the value i'm returning to the function are taken putting a higher if as i did.
This isn't going to do what you probably expect
if(A<=c<=Z)
... for all sorts of reasons. Firstly, the values of A and Z are uninitialized. Second, the logic is written to be read by a mathematician, not a C compiler.
You almost certainly wanted this:
if('A'<=c && c<='Z')
... and remove the four variables char A,Z,a,z;
Note that use of character constants such as 'A' and 'Z' assumes a runtime environment using ASCII character sets. If you're interested in a more portable solution, you can look up isupper() and islower()

Using pointers to count _ and ! in a string outside of the main function in C

I am working on an assignment for school and am having trouble getting the correct output. I am unsure if there is a problem with my loop or a problem with the method of saving values with pointers. When I run the code I end up with something like this:
Output: There are 369224989 underscores and 0 exclamation points in the sentence.
The assignment specifies to use the prototype and the getchar() function to read the input. I feel like since the first value is so high it is an issue with my loop but I have been working on this for two days and haven't seen anything wrong with it (though I could be staring through it at this point).
In addition I get these warnings when I try and compile the program:
characters.c:28: warning: value computed is not used
characters.c:31: warning: value computed is not used
This makes me think that maybe it isn't communicating properly with the main function.
#include<stdio.h>
//this function prototype was required for the assignment
void count(int* num_, int* num_exclamation);
// intended to count the number of _ and ! in a string using pointers
int main()
{
int num_, num_exclamation;
count(&num_, &num_exclamation);
return 0;
}
void count(int* p_num_, int* p_num_exclamation)
{
char ch;
*p_num_ = *p_num_exclamation = 0;
//attempts to scan a string get the first character
printf("Enter a sentence: ");
ch = getchar();
//attempts to loop while incrementing if it is a ! or _
while(ch != '\n')
{
if(ch == '_')
*++p_num_;
if(ch == '!')
*++p_num_exclamation;
ch = getchar();
}
//prints result
printf("Output: There are %d underscores and %d exclamation points
in the sentence.\n", *p_num_, *p_num_exclamation);
}
This is the second time I have really interacted with pointers with the first being the other half of this assignment which is working properly. I am not particularly comfortable with them yet nor aware of all of their nuances. Any advice to get me looking in the right place would be greatly appreciated.
You have Undefined behavior in your code. *++p_num_; increments the pointer first and then it dereferences it. The value of it is not used. And this way, the pointer points to some memory which are not the variables you supposed it to be. Then you dereference it - that location contains indeterminate value and you print it. Accessing some memory which you don't have permisssion to is - UB.
(*p_num_)++
is the one you wanted. This holds for the other variable also - namely p_num_exclamation. Also return value of getchar is int not char - you should use int to hold the value returned by getchar.

Loop through user input with getchar

I have written a small script to detect the full value from the user input with the getchar() function in C. As getchar() only returns the first character i tried to loop through it... The code I have tried myself is:
#include <stdio.h>
int main()
{
char a = getchar();
int b = strlen(a);
for(i=0; i<b; i++) {
printf("%c", a[i]);
}
return 0;
}
But this code does not give me the full value of the user input.
You can do looping part this way
int c;
while((c = getchar()) != '\n' && c != EOF)
{
printf("%c", c);
}
getchar() returns int, not char. And it only returns one char per iteration. It returns, however EOF once input terminates.
You do not check for EOF (you actually cannot detect that instantly when getchar() to char).
a is a char, not an array, neither a string, you cannot apply strlen() to it.
strlen() returns size_t, which is unsigned.
Enable most warnings, your compiler wants to help you.
Sidenote: char can be signed or unsigned.
Read a C book! Your code is soo broken and you confused multiple basic concepts. - no offense!
For a starter, try this one:
#include <stdio.h>
int main(void)
{
int ch;
while ( 1 ) {
ch = getchar();
x: if ( ch == EOF ) // done if input terminated
break;
printf("%c", ch); // %c takes an int-argument!
}
return 0;
}
If you want to terminate on other strings, too, #include <string.h> and replace line x: by:
if ( ch == EOF || strchr("\n\r\33", ch) )
That will terminate if ch is one of the chars listed in the string literal (here: newline, return, ESCape). However, it will also match ther terminating '\0' (not sure if you can enter that anyway).
Storing that into an array is shown in good C books (at least you will learn how to do it yourself).
Point 1: In your code, a is not of array type. you cannot use array subscript operator on that.
Point 2: In your code, strlen(a); is wrong. strlen() calculates the length of a string, i.e, a null terminated char array. You need to pass a pointer to a string to strlen().
Point 3: getchar() does not loop for itself. You need to put getchar() inside a loop to keep on reading the input.
Point 4: getchar() retruns an int. You should change the variable type accordingly.
Point 5: The recommended signature of main() is int main(void).
Keeping the above points in mind,we can write a pesudo-code, which will look something like
#include <stdio.h>
#define MAX 10
int main(void) // nice signature. :-)
{
char arr[MAX] = {0}; //to store the input
int ret = 0;
for(int i=0; i<MAX; i++) //don't want to overrrun array
{
if ( (ret = getchar())!= EOF) //yes, getchar() returns int
{
arr[i] = ret;
printf("%c", arr[i]);
}
else
;//error handling
}
return 0;
}
See here LIVE DEMO
getchar() : get a char (one character) not a string like you want
use fgets() : get a string or gets()(Not recommended) or scanf() (Not recommended)
but first you need to allocate the size of the string : char S[50]
or use a malloc ( #include<stdlib.h> ) :
char *S;
S=(char*)malloc(50);
It looks like you want to read a line (your question mentions a "full value" but you don't explain what that means).
You might simply use fgets for that purpose, with the limitation that you have to provide a fixed size line buffer (and handle - or ignore - the case when a line is larger than the buffer). So you would code
char linebuf[80];
memset (linebuf, 0, sizeof(linbuf)); // clear the buffer
char* lp = fgets(linebuf, sizeof(linebuf), stdin);
if (!lp) {
// handle end-of-file or error
}
else if (!strchr(lp, '\n')) {
/// too short linebuf
}
If you are on a POSIX system (e.g. Linux or MacOSX), you could use getline (which dynamically allocates a buffer). If you want some line edition facility on Linux, consider also readline(3)
Avoid as a plague the obsolete gets
Once you have read a line into some buffer, you can parse it (e.g. using manual parsing, or sscanf -notice the useful %n conversion specification, and test the result count of sscanf-, or strtol(3) -notice that it can give you the ending pointer- etc...).

How do I update an int variable using my getline(s, lc) function without using "pointers"? (C)

I am doing exercise 2-5 in K&R C and I decided to implement a function called getline(s, lc) where s is the string to concatenate the characters with and lc is an integer to count lines.
You guys might say that this is a possible duplicate but I am going to first explain how this question is different.
Update (int) variable in C inside a function [duplicate] - This involves pointers but I am asking how I can update a variable without using pointers. I am a "n00b" at it.
How to change variable? - This also involves pointers and doesn't have an accepted answer.
I want the program to run like this: (Overall)
String 0: the big brown fox jumped over lazy dog
String 1: lazy
First Occurrence: 29
I want my program to work that way in overall; Ask a user to input two string and if one character in String 1: matches in String 0: it will return the first occurrence of that character.
But let's focus on the first part where I implemented getline(s, lc). Putting a character in string is possible but I want to know if it's possible updating an integer variable.
As of now, this is how my program runs:
String 0: DEEP BLUE SKY
String 0: BLUE CAKE
The prompt where BLUE CAKE is should be String 1: not String 0: again.
/* getline: gets the character input and convert it into a string. */
void getline(char s[], int lc)
{
int c, i, lim;
lim = LIMIT;
i = 0;
printf("String %d: ", lc);
while (lim > 0) {
c = getchar();
if (c == '\n' || c == EOF) {
lim = 0;
}
else {
s[i] = c;
++i;
}
}
++lc;
s[i] = '\0';
}
And here's the link.
Is there a way to update an integer variable lc by 1 using a function without using pointers?
I want to solve this problem using what I learned so far in the book keeping away advanced topics.
You can by making the function return the value
int getline(char s[], int lc)
{
...
return ++lc;
}
The string is passed by reference to the function so any changes you do to the string will anyway be visible outside the function. In effect char s[] passes the address where the string resides so you are free to change its contents inside your getline function.
The problem with your getline function is that it does not know the max size of the array since there is no such information available in the array itself. You should add the size as an argument as well to avoid memory overwrites.
e.g.
int getline(char s[], int maxlen, int lc)
You can have the function return the integer as its return value.
You can either return lc from your function or use lc as a global variable (better to avoid using global variable).

Need help restructuring loop/getting simple average code to work.

First time working with C and I was asked to do a simple average function WITHOUT scanf (only using getchar) for my Systems class. I ended up writing an unnecessarily complicated loop just to get my code to compile and even after compiling+running it doesn't seem to do anything after taking in the keyboard input.
#include <stdio.h>
#include <stdlib.h>
//average program
//use getchar to get numbers separately instead of scanf and integers.
//Not sure why. Most likely to build character.
int main (int argc, const char * argv[])
{
char x,z;
float avg;
int tot,n,b;
printf("Input Integer values from 1 to 100. Separate each value by a space. For example: 23 100 99 1 76\n");
ret:
x=getchar();
while( x != '\n' );
{
if(x==isspace(x))
{ goto ret;}
opd:
z=getchar();
if ((z == isspace(z)))
{
b = x - '0';//subtracting 0 from any char digit returns integer value
tot +=b;
n++;
goto ret;
}
else if(z == '\n')
{
b = x - '0';
tot +=b;
n++;
goto end;
}
else
{
x = x*10;
x = x + z;
goto opd;
}
}
end:
avg=tot/n;
printf("Taking of the average of the values. The average is %1.2f\n",avg);
return avg;
}
The semicolon in while(...); causes an infinite loop, it's the same as saying: while(...) continue;
You should use only one loop, and you should try to use only one call to getchar() ... it's too confusing with multiple getchar() calls and your code is trying to throw away the first line the way it's written.
Definitely get rid of the goto statement, your instructor won't like them and they are quite unnecessary. (Do read up on break and continue.)
In C parsers calling getchar() directly, it's useful to be able push a character back on the input stream. See man 3 ungetc or just write a simple wrapper around getchar(). You should only need one character of pushback at the end of a parser loop.

Resources