Inputting structure members into printf function and too many arguments error - c

Hi can anybody tell me the issue of what's going on in the printf function? I keep getting an error of
warning: format ‘%i’ expects argument of type ‘int’, but argument 2
has type ‘char *’ [-Wformat=] time2.hour, time2.min, time2.sec,
time3.hour, time3.min, time3.sec);
and then
warning: too many arguments for format [-Wformat-extra-args]
Anybody give some pointers as to how to fix? Thanks
#include <stdio.h>
struct time
{
int hour;
int min;
int sec;
};
int main (void)
{
struct time time1, time2, time3;
struct time elapsed_time (struct time time1, struct time time2);
printf("Enter your first time (hh:mm:ss) : ");
scanf ("%i:%i:%i", &time1.hour, &time1.min, &time1.sec);
printf("Enter your second time (hh:mm:ss) : ");
scanf ("%i:%i:%i", &time2.hour, &time2.min, &time2.sec);
time3 = elapsed_time(time1,time2);
printf("The time difference between %.2i:%.2i:%.2i & %.2i:%.2i:%.2i",
"is %.2i:%.2i:%.2i.\n", time1.hour, time1.min, time1.sec,
time2.hour, time2.min, time2.sec, time3.hour, time3.min, time3.sec);
return 0;
}
struct time elapsed_time (struct time time1, struct time time2)
{
struct time time3 = { 0, 0, 0 };
time3.hour = time2.hour - time1.hour;
time3.min = time2.min - time1.min;
time3.sec = time2.sec - time1.sec;
return time3;
}

It looks like you have two string literals in your long printf statement, but the printf statement only allows one string at the beginning, and it must be the one that contains all the %.2i format placeholders.
Right now, printf gets the first one, and then tries to use the second string as an input argument to the first.
Join those two strings into 1 string, and it should work.

Related

C Insert int and doubles inside structure

I have a problem with a small project, I have to create a structure containing a person's data,I have to do data entry via a function using pointers.
I don't understand why when I try to enter the weight the program ends with this error:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
I made an example of the code that is giving me problems:
typedef struct{
char name[DIM];
char surname[DIM];
int height;
float weight;
}Record;
int main() {
Record subj;
insRecord(&subj);
}
void insRecord(Record *subj){
printf("\nName ");
scanf("%64[^\n]s", subj->name);
cleanBuffer();
printf("\nSurname ");
scanf("%64[^\n]s", subj->surname);
cleanBuffer();
printf("\nEight ");
scanf("%3s", subj->height);
cleanBuffer();
printf("\nWeight ");
scanf("%6s", subj->weight);
cleanBuffer();
}
int cleanBuffer(){
int cont= 0;
char c;
do{
cont++;
c = getchar();
}while(c != '\n');
return cont;
}
(I only wrote the main functions).
Furthermore, compiler is giving warnings on height and weight scanf() statements:
Format specifies type 'char *' but the argument has type 'int' (for height)
Format specifies type 'char *' but the argument has type 'double' (for weight)
Could you tell me how can I solve?
PS the project is divided into several files (3 files).
In main.c I wrote the insRecord() function, in struct.h I wrote the Record structure, in struct.c I wrote cleanBuffer() function.
You are reading a string (%s) and try to store that in a float. If you use the flag %f for weight and %d for height it will probably work better. Remember that you should provide a pointer to the float and int that you want to store the data in, you are not doing that in your example.
Have a look at the scanf documentation:
https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
Good luck

How can I allow a user to input values for an array with a specified initial size?

I want to be able to ask a user of this code for four values for an array. I have some code, but it prints an error that I cannot seem to get around. I'm trying to model some of my code after the example in this video tutorial: https://youtu.be/IPYA3b3_nyk?list=PL6gx4Cwl9DGAKIXv8Yr6nhGJ9Vlcjyymq , however, I cannot seem to get it to compile without errors.
The error goes as follows:
In function ‘main’:
intitializeint.c:12:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("Enter value %d. \n", &i+`);
^
I've tried using printf() and scanf() for each prompt for a value but discovered that this tutorial and tried to mimic it. I've tried rearranging the "&i+1" but it just shoots the same error back. I want to have an increment so that in the output, it shows as if the array started at 1.
#include <stdio.h>
#include <stddef.h>
void printArray(int n[]);
int main(void)
{
int i;
int n[4];
for (i = 0; i < 5; ++i) {
printf("Enter value %d. \n", &i+1);
scanf("%d", &n[i]);
}
printf("%s%13s\n", "Element", "Value");
printArray(n);
return 0;
}
void printArray(int n[])
{
int i;
for (size_t i = 0; i < 4; ++i) {
printf("%7zu%13d\n", i, n[i]);
}
}
When you wrote &i you accidentally created a pointer to i. Your pointer will have type int *, because it is a pointer to an int. The %d format specifier expects an int, not a pointer to an int, so that is why the compiler is giving you that error. (You should re-reread that error and make sure every word of it makes complete sense to you now.)
The solution is to remove the erroneous & operator:
printf("Enter value %d.\n", i + 1);

Storing user input into linked list - C

I have an assignment for C beginner class: I'm supposed to create a structure that has one variable (named value) and one pointer to the list. I'm supposed to prompt the user for 5 values as input and store them in the linked list. Then print out the list. I can't figure out how to store input into the list. I did manage to write a program in which I initialize the 5 values. But I don't know how to accept input and store it into the list.
Here's the working program where I initialize the values:
#include <stdio.h>
struct list
{
double value;
struct list *nextVal;
};
int main()
{
struct list v1 = {10};
struct list v2 = {17.97};
struct list v3 = {166};
struct list v4 = {2};
struct list v5 = {387.55};
struct list *first;
first = &v1;
v1.nextVal = &v2;
v2.nextVal = &v3;
v3.nextVal = &v4;
v4.nextVal = &v5;
v5.nextVal = NULL;
printf("All the values are: %.2f, %.2f, %.2f, %.2f, %.2f.",
first->value,v1.nextVal->value,v2.nextVal->value,
v3.nextVal->value,v4.nextVal->value);
return 0;
}
Here's a program where I tried getting user input and storing that into the list. (I only have 2 values instead of 5, cuz it's easier to work with that when trying to make it work.) When I compile this program, I get no errors. When I run it, I am properly prompted for the two input values; however, when the output that the program prints just writes 0 for both values. My assumption is that I'm storing the value into the list wrong - because I don't know how it's actually done. (Can't find any info in my textbook or online.) Last night someone commented on a different question I had to try using breakpoint to find out exactly where the problem is - I've been trying to figure it out since then but don't know how to do that yet. (I'm assuming it's something very simple - but everywhere I looked online, people explain it in a way that seems like I'm supposed to know what they're talking about - which I don't - And honestly, even if I could figure it out, I still wouldn't know what to do with that information, since I just can't find any information on how to store user input into a linked list.) Anyways, so here's my trial program that complies and runs but gives me 0 for both final values:
#include <stdio.h>
struct list
{
double value;
struct list *nextVal;
};
int main()
{
double val1,val2;
printf("Please enter a number: ");
scanf("%f",&val1);
printf("Please enter a number: ");
scanf("%f",&val2);
struct list v1 = {val1};
struct list v2 = {val2};
struct list *first;
first = &v1;
v1.nextVal = &v2;
v2.nextVal = NULL;
printf("The two values entered are %.2f and %.2f.",
first->value,v1.nextVal->value);
return 0;
}
Thank you in advance! And I'm reaaaally a beginner - so even if you suggest something super easy - I might have no clue what it is..so please explain! Thank you!
scanf("%f",&val1);
%f requires a float variable but the given variable is a double. Use %lf for double.
scanf("%lf",&val1);
Your compiler should have given you a warning for that and you should always heed those and resolve them:
warning: format ‘%f’ expects argument of type ‘float *’, but argument 2 has type ‘double *’ [-Wformat=]
scanf("%f",&val1);
A few extra words of advice though they are not directly addressing your question:
Always check the function return values. Specifically, check scanf to ensure that the expected input was parsed. The code as it is will fail if the user enters something unexpected.
Break up your code into functions. Specifically, make a seperate insert function to add items to the linked list.
Use loops where you need to repeat code. Such as for the scanf calls. That way it can be easily extended when you want to take more input.
Try compiling with warnings on etc. At a minimum I use this...
gcc -Wall -pedantic -std=c11
Working version
include <stdio.h>
struct list
{
double value;
struct list *nextVal;
};
int main()
{
double val1,val2;
printf("Please enter a number: ");
scanf("%lf",&val1);
printf("Please enter a number: ");
scanf("%lf",&val2);
struct list v1 = {val1};
struct list v2 = {val2};
struct list *first;
first = &v1;
v1.nextVal = &v2;
v2.nextVal = NULL;
printf("The two values entered are %.2f and %.2f.",
first->value,v1.nextVal->value);
return 0;
}
You were scanning quotes and trying to assign it to a double. A good compiler would give you a warning..
scanf.c:14:14: warning: format specifies type 'float *' but the argument has type 'double *' [-Wformat]
scanf("%f",&val1);
~~ ^~~~~
%lf
scanf.c:16:14: warning: format specifies type 'float *' but the argument has type 'double *' [-Wformat]
scanf("%f",&val2);
~~ ^~~~~
%lf

Program crashes when reading first data point

I want to see what student have the best mark in the class.
So I make this ,but i don't know where I am wrong
struct Date {
char name[31];
float mark;
};
struct Date * Read(unsigned int n,struct Date *d){
int i;
for(i=0;i<n;i++){
getchar();
fgets(d[i].name, 31, stdin);
scanf("%f",d[i].mark);
}
return d;
}
int main(){
unsigned int n;
struct Date *d;
scanf("%u",&n);
d = (struct Date*) malloc(n*sizeof(struct Date));
d=Read(n,d);
free(date);
return 0;
}
after i read the mark the program crash.
Can someone help me and explain what to change?
Thanks a lot.
The crash is most likely due to this:
scanf("%f",d[i].mark);
You should pass the address as argument to read a float value. It should be:
scanf("%f", &d[i].mark);
Technically, this is undefined behaviour..
Compile with all warnings enabled. gcc warns even without any specific options:
warning: format %f expects argument of type âfloat *â, but argument 2 has type double [-Wformat=]
scanf("%f",d[i].mark);

How to use atoi conversion in C using gets_s - example code included

I'm teaching myself about structures in C, and am having trouble compiling this code:
#include <stdio.h>
#include <stdlib.h>
struct Date {
int Month;
int Day;
int Year;
};
void AddDecade(struct Date);
int main(int argc, char *argv[]) {
struct Date BDay;
char buffer[50];
printf("What month were you born? ");
BDay.Month = atoi(gets_s(buffer, 50));
printf("What day were you born? ");
BDay.Day = atoi(gets_s(buffer, 50));
printf("What year were you born? ");
BDay.year = atoi(gets_s(buffer, 50));
printf("You were born on %d, %d, %d?\n", BDay.Month, BDay.Day, BDay.Year);
AddDecade(BDay);
printf("You will be 10 years older on %d, %d, %d\n", BDay.Month, BDay.Day, BDay.Year);
}
void AddDecade(struct Date Target) {
Target.Year += 10;
}
The author of the code compiled it without error on a Windows machine, but on my Linux machine gcc gives the following errors:
07_04_structures2.c: In function ‘main’:
07_04_structures2.c:18:5: warning: passing argument 1 of ‘atoi’
makes pointer from integer without a cast [enabled by default]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but
argument is of type ‘int’
07_04_structures2.c:21:5: warning: passing argument 1 of ‘atoi’ makes
pointer from integer without a cast [enabled by default]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but
argument is of type ‘int’
07_04_structures2.c:24:9: error: ‘struct Date’ has no member named
‘year’
07_04_structures2.c:24:5: warning: passing argument 1 of ‘atoi’ makes
pointer from integer without a cast [enabled by default]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but
argument is of type ‘int’
Given this line:
BDay.Month = atoi(gets_s(buffer, 50));
My understanding is that gets_s copies a maximum of 50 bytes of input into buffer, and passes a pointer to the variable 'buffer', to atoi, but according to this error:
note: expected ‘const char *’ but argument is of type ‘int’
perhaps gets_s is at fault here? I've never used it before...
I'd be very thankful for a detailed explanation of what's wrong, and how to fix it.
Thanks a lot!
Update:
I implemented all of your recommendations and have come up with the following working code:
#include <stdio.h>
#include <stdlib.h>
struct Date {
int Month;
int Day;
int Year;
};
struct Date AddDecade(struct Date);
int main(int argc, char *argv[]) {
struct Date BDay;
char buffer[50];
char *buffer_end;
printf("What month were you born? ");
fgets(buffer, sizeof(buffer), stdin);
BDay.Month = strtol(buffer, &buffer_end, 10);
printf("What day were you born? ");
fgets(buffer, sizeof(buffer), stdin);
BDay.Day = strtol(buffer, &buffer_end, 10);
printf("What year were you born? ");
fgets(buffer, sizeof(buffer), stdin);
BDay.Year = strtol(buffer, &buffer_end, 10);
printf("You were born on %d, %d, %d?\n", BDay.Month, BDay.Day, BDay.Year);
BDay = AddDecade(BDay);
printf("You will be 10 years older on %d, %d, %d\n", BDay.Month, BDay.Day, BDay.Year);
}
struct Date
AddDecade(struct Date Target) {
Target.Year += 10;
return Target;
}
This has been a great learning experience for me! Thank you! :)
gets_s is a function defined in C11 and it is defined as an optional extension.
You have to compile your program with C11 support otherwise the gets_s function is not declared in stdio.h. When the function is not declared in stdio.h and there is no available prototype for the function like in your program, gcc will then implicity provide a prototype for gets_s that returns an int (implicit function declaration).
On gcc compiling with C11 is done with option -std=c11 on gcc 4.7 and -std=c1x in older gcc. Note that as of today support of C11 in gcc (and Linux C libraries like glibc or eglibc) is still very incomplete and gets_s may be also not declared even when C11 option is enabled (not to mention the extension is optional).
get_s() isn't implemented in the Linux C library, so the compiler assumes the default of it being a function that returns and int takes whatever (promoted) parameters you pass it.
You'll need to recode to avoid using gets_s(). Probably the simplest fix is to use fgets() instead. Change the lines similar to:
BDay.Month = atoi(gets_s(buffer, 50));
with:
fgets(buffer, sizeof(buffer), stdin);
BDay.Month = atoi(buffer);
gets_s is not standard function in most versions of C language.
Since you didn't declare get_s, the compiler assume (as default) that it returns int, and hence the error.
Also, look at the error at line 24. (you should change year to Year)

Resources