how to make a multipurpose input function input(); in C? - c

i am a beginner in C programming, and while making a program i wondered if there can be a universal input function input(); be made, such that the variable name given in braces be asked for input like this:
input(a);
result:
enter value of a: 10
now (after the input) if i write like this in any program like:
#include<stdio.h>
main()
{
int a;
float b;
char c;
input (a);
printf("value of a = %d\n",a); // 1
input(b);
input(c);
printf("value of b = %f\n",b); // 2
printf("c = %c\n",c); // 3
}
then output should be like this:
output:
enter value of a: 10
***value of a = 10***
enter value of b: 10.0
enter value of c: D
***value of b = 10.000000***
***c = D***
i.e the function parameter should take values acording to the type of variable concerned(like char,float,int etc) like if a were char then value entered in a would be saved accordingly.
i thought to implement it using structures but i am not able to think, how to link the actual parameter passsed in input(); with the struct members
update: i have written the lines 1,2,and 3(in comments: the printf() functions) just to show that the values of a,b, and c are aptly/rightfully stored in their corresponding types

With literally the same syntax as you've written - no, you need C++ features for this (function overloading), but it worth knowing that internally it will just use set of different functions, so actually it's almost exactly the same as input_int, input_char, etc.
You could use union (probably union within a struct - you need to save actual type somewhere), but it's quite different approach.
Macros (especially C11 _Generic's, if you could use C11 features) could be good alternative too.

Related

Manipulating C function

Is there exist a way to manipulate C function some how
for eg - we know C printf() function return Number of character printed to the console.
So is there any way that i can get number of character but not letting printf() function print to console. using same printf() from stdio.h
I know return is the last statement to get executed in a function hence what i am asking may be impossible but i do want to hear from the community i.e is my hypothesis i.e manipulating c function is possible or not?
If you have access to the source code and you're able to recompile it with your changes, then sure, you can do it. Consider this:
int foo(int a, int b)
{
int c = 4;
int d = 8;
int f = c * a;
int g = d * b;
int h = f + g;
return h;
}
If you want the value stored in f, there are a couple of ways to do it: 1) you peak into the stack with inline assembly (non-portable, non-reliable), 2) you change the code to expose the variable. Notes on "peaking the stack": what if the architecture does not have a stack? What if the values are all on registers? What if the compiler optimized all the function calls to inline calls? What if...?
Because if you look at the function from the outside, all the function is... is this:
int foo(int a, int b);
You can get an integer from it if you pass two integers to it as arguments. That's all you can do with the API. There is no way in C you can get the value of f or g.
In the analogy, f and g are printf's internal state, and you can not access it. Functions are designed to work as perfect black boxes: it gives you an output based on your input, but how it does it doesn't matter.

Declare multiple integer variables in C

Before i start, I am not good at English so I use a translator, so you may not understand well.
I'm so sorry. But the content of the question is easy, so there is probably no difficulty understanding.
One day I don't remember very well, but I saw a code similar to the one below.
#include <stdio.h>
int main(){
int a,b,c = 1,d,e;
return 0;
}
At that time, I just let it go. But now that I think about it, I'm curious.
So I checked the value of C, and it was printed 1.
And I changed 1 to 0 and confirmed that the value of C was zero.
This result was the same for the other numbers.
I've never seen a code like this before.
In the meantime, I knew that to declare a number of variables, I would have to do as the code below.
int a = 1, b = 2, c = 3;
But it wasn't what I knew.
After several experiments, I found that a,b,c,d,e were independent variables.
Except for C, a,b,d,e contained garbage value.
I wonder why this is grammatically possible and why the values are not allocated in order from left to right.
Once again, I'm sorry for using the translator.
int a,b,c = 1,d,e;
is the same as
int a;
int b;
int c = 1;
int d;
int e;
Except for C, a,b,d,e contained garbage value - This is because only C is both declared and initialized with the value 1. Others are just declared in a random memory location, hence has garbage values
I wonder why this is grammatically possible - It is a right syntax still. See the answer by #pmg
In the meantime, I knew that to declare a number of variables, I would have to do as the code below. int a = 1, b = 2, c = 3; - Here you are actually declaring as well as initializing them with different values. You can always declare any number of variables (of the same datatype) in a single statement.

Use printf for ternary operator arguments with mixed types

I have a tricky, but interesting question. Hang in there!
Let's assume I write embedded code, and I am in a system where I have to store values in 16bit unsigned to be compatible with other systems. Some values have a decimal part, but luckily I know the position of the separator in advance (fixed point).
Now let's consider this structure:
typedef struct{
// pointer to a function that computes the "real" value
float (*getRealValue)(void);
// pointer to a function that computes a "stringified" value
bool (*getCustomString)(char *);
} var_info_t;
And let's declare one variable var1, which is a temperature:
uint16_t var1 = 1530; // means 15.3°C
float var1_toFloat(void){ return (float)var1/100; } // should return 15.3
var_info_t var1_info = { .getRealValue = var1_toFloat, .getCustomString = NULL };
and another variable var2, which happens to be more like a boolean:
uint16_t var2 = 1; // means Enabled
bool var2_toString(char* buffer){ // should write "Enabled"
if(buffer) sprintf(buffer, "%s", var2 ? "Enabled" : "Disabled");
return true;
}
var_info_t var2_info = { .getRealValue = NULL, .getCustomString = var2_toString };
Now I want to display these values together on a screen, with some fancy formatting that can change depending of where these value are written on the screen.
(I just have to call TEXT_SetText(int widget_id, char* text) to update my GUI widgets.)
What I want to accomplish is to create a "wrapper" to TEXT_SetText() like this...
static char text[128], buf[2][32];
#define GET_VAR_AUTO(var_info, i) \
((var_info.getCustomString != NULL && var_info.getCustomString(buf[i])) ? buf[i] : \
(var_info.getRealValue != NULL ? var_info.getRealValue() : 0))
void my_TEXT_SetText(int widget_id, char* format, var_info_t a, var_info_t b){
snprintf(text, sizeof(text), format, GET_VAR_AUTO(a, 0), GET_VAR_AUTO(b, 1));
TEXT_SetText(widget_id, text);
}
...so that calling my_TEXT_SetText(0, "Regulator is %s at %.1f\260C", var2_info, var1_info);
will display a nice Regulator is Enabled at 15.3°C inside my box.
The real advantage here is that you can update the text in real-time just by calling this same function periodically from "anywhere" (without "knowing anything" about the variables or their values). Also you can simply expand the number of variables inside the same text by increasing the number of snprintf arguments.
The problem: the GET_VAR_AUTO macro is not syntactically correct because it mixes char* from buf[i] and float from getRealValue() in the possible results of the ternary operator:
error: type mismatch in conditional expression
BUT, knowing that sprintf is a variadic function, that treats its arguments according to the types given in the format string (%f, %s, ... thanks to the va_arg() function), is there a way to find a common abstract type for the ternary operator which would be accepted by the sprintf ?
I tried a lot of things but I can't get the char* and float to work simultaneously.
(Unfortunately I'm using C, not C++)
No, there simply isn't any generic type, and it cannot be done in C except in very special cases.
For example floating point arguments are passed in floating point/SSE registers on x86-64 for example, whereas integer arguments in integer registers. There is no way of passing a variable argument that is passed as "both" in variable arguments, because in a function call like
printf("%f %d", f, d );
R1 F1 R2
The arguments would be passed in two general-purpose registers and one floating point register like so, whereas in
printf("%d %f", d, f );
R1 R2 F1
they would be passed in the same registers again!
Indeed,
#include <stdio.h>
int main(void) {
printf("%f %s\n", "hello world", 2.5);
}
compiled with GCC for x86-64/Linux, and run, will not print any random garbage but exactly 2.50000 hello world. So on x86-64 the most you could do is to pass the last argument in both a floating point and a general purpose register.
What you could do is to write your own printf-like function that would accept pointers to void for the arguments, then dereference them based on the actual type.
It will still be quite tricky.
If you're really desperate, consider trying libffi.
Define
#define FLOAT_STR_SIZE_MAX (32) /* or what ever you feel suits */
#define FTOA(b, s, x) \
(snprintf(b, s, "%f", x), b)
and replace
(var_info.getRealValue != NULL ? var_info.getRealValue() : 0)
by
FTOA((char[FLOAT_STR_SIZE_MAX]){'\0'},
FLOAT_STR_SIZE_MAX,
(var_info.getRealValue != NULL ? var_info.getRealValue() : 0.))
:-)

Searching for all integers that occure twice in a vector

I got the task in university to realize an input of a maximum of 10 integers, which shall be stored in a one dimensional vector. Afterwards, every integer of the vector needs to be displayed on the display (via printf).
However, I don't know how to check the vector for each number. I thought something along the lines of letting the pointer of the vector run from 0 to 9 and comparing the value of each element with all elements again, but I am sure there is a much smarter way. I don't in any case know how to code this idea since I am new to C.
Here is what I have tried:
#include <stdio.h>
int main(void)
{
int vector[10];
int a;
int b;
int c;
a = 0;
b = 0;
c = 0;
printf("Please input 10 integers.\n\n");
while (a <= 10);
{
for (scanf_s("%lf", &vektor[a]) == 0)
{
printf("This is not an integer. Please try again.\n");
fflush(stdin);
}
a++;
}
for (b <= 10);
{
if (vector[b] != vector[c]);
{
printf("&d", vector[b]);
c++;
}
b++;
}
return 0;
}
Your code has several problems, some syntactic and some semantic. Your compiler will help with many of the former kind, such as
misspelling of variable name vector in one place (though perhaps this was a missed after-the-fact edit), and
incorrect syntax for a for loop
Some compilers will notice that your scanf format is mismatched with the corresponding argument. Also, you might even get a warning that clues you in to the semicolons that are erroneously placed between your loop headers and their intended bodies. I don't know any compiler that would warn you that bad input will cause your input loop to spin indefinitely, however.
But I guess the most significant issue is that the details of your approach to printing only non-duplicate elements simply will not serve. For this purpose, I recommend figuring out how to describe in words how the computer (or a person) should solve the problem before trying to write C code to implement it. These are really two different exercises, especially for someone whose familiarity with C is limited. You can reason about the prose description without being bogged down and distracted by C syntax.
For example, here are some words that might suit:
Consider each element, E, of the array in turn, from first to last.
Check all the elements preceding E in the array for one that contains the same value.
If none of the elements before E contains the same value as E then E contains the first appearance of its value, so print it. Otherwise, E's value was already printed when some previous element was processed, so do not print it again.
Consider the next E, if any (go back to step 1).

Variable Initialization in Function

I'm fairly new to coding and am currently learning C. In my C programming class, my instructor gave us the assignment of writing a program that uses a function which inputs five integers and prints the largest. The program is fairly simple even for me, but I'm facing some problems and was hoping to get some advice.
#include <stdio.h>
int largest(int x);
int main(void) {
int integer1;
largest(integer1);
return 0;
}
int largest(int x) {
int i;
for (i = 0; i < 5; i++) {
printf("Enter an integer: ");
scanf_s("%d", &x);
}
return x;
}
This is the code that I have written. The main problem that I am having is that in my main method, the IDE tells me to initialize the value of integer1. However, I'm not really sure how to do that because I'm supposed to input the value within the largest() method via the scanf_s function. How may I solve this?
The problem is here, the warning message is to warn you about the potential pitfall of using the value of an uninitialized automatic local variable. You made the call like
largest(integer1);
but you ignore the return value, so the integer1 remains uninitialized.
Remember, in view of largest(), x is a local copy of the actual argument passed to that function, any changes made to x won't be reflecting to the caller.
That said, your code is nowhere near your requirement, sorry to say. A brief idea to get there would be
Create a function.
Create a variable (say, result) and initialize with minimum possible integer value, INT_MIN
Loop over 5 times, take user input, compare to the result value, if entered value found greater, store that into result, continue otherwise.
return result.
I know that normally help for assignments shouldn't be given but I have to say that you might need to rethink what you want to do.
You are inputting an integer to the function named largest. But why are you only inputting a single integer to a function that should return the largest value. You can't do much with a single number in that case.
You should instead be inputting say an array of 5 values(as said in your assignment) to the function and let it return the largest.
The order would then be:
Read 5 values and save to an array
Call the function largest with the array as input
Let the function do it's work and return the largest value
Do what ever you want with the largest value
But if you only want to remove the warning simply type
int integer1 = 0;

Resources