How to print the days of the week using a structure member? - c

I want to print the days of the week in this program but it doesn't work, what can I do to fix it ?
#include<stdio.h>
struct month{
int date[12];
char day[7];
}mon;
main()
{ int i;
strcpy(mon.day[0],"Sunday");
strcpy(mon.day[1],"Monday");
strcpy(mon.day[2],"Tuesday");
strcpy(mon.day[3],"Wednesday");
strcpy(mon.day[4],"Thursday");
strcpy(mon.day[5],"Friday");
strcpy(mon.day[6],"Saturday");
for(i=0;i<7;i++)
{
printf("Day %d is %c\n",i+1,mon.day[i]);
}
}

You are trying to store strings in char. However, a string is an array of char. Instead of this:
char day[7];
You need something such as:
char day[7][16];
Now you have 16 char to fit in a weekday, and you have that seven times, one for each day. Also, your print is wrong. To print strings, you need %s, not %c. %c is just for one single char:
printf("Day %d is %s\n", i + 1, mon.day[i]);
Another way of doing it is to have an array of char* instead of char and only storing the address of the strings rather than copying the strings:
char *day[7];
Then store the addresses like this:
mon.day[0] = "Sunday";
mon.day[1] = "Monday";
mon.day[2] = "Tuesday";
...
And print it the same way, with %s.

If you try to compile your program, your compiler will give you certain warnings. Like
Problem 1:
source_file.c:10:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main()
^
The proper signature of main() is int main(void), for usual hosted environments.
Problem 2:
source_file.c: In function ‘main’:
source_file.c:13:5: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
strcpy(mon.day[0],"Sunday");
^
source_file.c:13:5: warning: incompatible implicit declaration of built-in function ‘strcpy’
source_file.c:13:5: note: include ‘<string.h>’ or provide a declaration of ‘strcpy’
You'd need to include string.h header file which contains the declaration for strcpy().
Problem 3:
source_file.c:13:12: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(mon.day[0],"Sunday");
This indicates, the first argument of strcpy() expects a char *, but you're passing a char, casted to an int.
This is the most important point here, as you'd see, you need to pass a buffer which can contain the content from the copied string. Thu's, you'd need
day to be a 2-D array
use day[i] to store the content
use %s to print the content thereof.

For constants like day and month, better constructed like the following, unless you are practicing with struct.
#include<stdio.h>
int main()
{
const char *day[] = {"Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday" };
//^^^^^ array of strings.
for(int i=0;i<7;i++)
printf("Day %d is %s\n",i+1,day[i]);
return 0;
}

Related

C function to return greatest ascii value

I'm trying to create a C function to return a pointer to the char with the greatest ascii value in a string, but my function is returning 'H' instead of 'o'. I think it's something to do with the if statement in the for loop but I'm not sure what the problem is. Any help is appreciated. Thanks!
char * select_max(char str[]);
int main(void) {
printf("%c\n",select_max("Hello"));
printf("All tests passed successfully.\n");
}
char *select_max(char str[]){
int length = strlen(str);
if(length<1){//returns 0 if string length is less than one
printf("Invalid string.\n");
return 0;
}
char *max = str;
for(int i=0;i<length;i++){
if(str[i] > max){
max = str[i];
}
}
return *max;
}
Try adding a printout so that you can see your bug in action. For example, just before your if:
printf("%c > %c = %d\n", str[i], max, (str[i] > max));
I believe this will quickly reveal the bug. [Hint: there are 5 bugs in your program.]
Compiler is nice enough to give you quite useful warnings, you should follow them, read carefully and try to understand. It won't point out your logical errors but you can deduce these too in this case.
main.c: In function 'main':
main.c:4:5: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
printf("%c\n",select_max("Hello"));
^~~~~~
main.c:4:5: warning: incompatible implicit declaration of built-in function 'printf'
main.c:4:5: note: include '<stdio.h>' or provide a declaration of 'printf'
main.c: In function 'select_max':
main.c:10:18: warning: implicit declaration of function 'strlen' [-Wimplicit-function-declaration]
int length = strlen(str);
^~~~~~
main.c:10:18: warning: incompatible implicit declaration of built-in function 'strlen'
main.c:10:18: note: include '<string.h>' or provide a declaration of 'strlen'
You first need to include the libraries that you use functions from, printf is from stdio.h and strlen is from string.h.
main.c:22:12: warning: returning 'char' from a function with return type 'char *' makes pointer from integer without a cast [-Wint-conversion]
return *max;
^~~~
You appear to be confusing chars with char*s. Since select_max is logically supposed to return just a character, (and you are already returning a char) declaring it as below will suffice.
#include<stdio.h>
#include<string.h>
char select_max( char str[] );
main.c:19:17: warning: assignment to 'char *' from 'char' makes pointer from integer without a cast [-Wint-conversion]
max = str[i];
And in the implementation of select_max, there is a similar problem. The temporary variable to hold the highest character is of type char* where it just needs to be a char:
char select_max(char str[]){
// ^___
int length = strlen(str);
if(length<1){//returns 0 if string length is less than one
printf("Invalid string.\n");
return 0;
}
// Initialize it to 0, has to be lower than any ASCII letters in order your algorithm to work. DO NOT leave it uninitialized.
char max = 0; // <---
for(int i=0;i<length;i++){
if(str[i] > max){
max = str[i];
}
}
return max;
}
The code above defines max as a char and initializes it to 0. Assigning str to it was pointless anyway. You are iterating through your string one character at a time and storing the character in a temporary container.
Note that the code in the for loop had already written as if it was of type char.
The same algorithm of course can be implemented in various ways but I suppose this was what you were trying to do.

"segmentation error (core dumped)" Using function and pointers

I am learning functions in C and having following problem with so many warnings :-(
code is as follows
#include <stdio.h>
void main(){
int a,c;
char *b; // declaring a pointer
char string[100]="something";
b = string; // assigning a pointer.. doing
printf("\n %s \n\n %s",string,*b); // doing this as a verification of the pointer, which is good - no seg faults
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("%s",*b);//segmentation fault core dumped:-'(
}
void find(int x, int y,char *b){
if(x>y)
*b = "a is greater than b";
else if(x=y)
*b = "both the values are equal";
else
*b = "b is greater than a";
}
warnings while compiling:--
function.c: In function ‘main’:
function.c:7:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
printf("\n %s \n\n %s",string,*b); /*doing this jus to check is pointer working but no it is *not.segmentation error here "core dumped":-'(
^
function.c:12:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s",*b);//segmentation fault core dumped:-'(
^
function.c: At top level:
function.c:14:6: warning: conflicting types for ‘find’ [enabled by default]
void find(int x, int y,char *b){
^
function.c:11:2: note: previous implicit declaration of ‘find’ was here
find(a,c,*b);
^
function.c: In function ‘find’:
function.c:16:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "a is greater than b";
^
function.c:18:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "both the values are equal";
^
function.c:20:6: warning: assignment makes integer from pointer without a cast [enabled by default]
*b = "b is greater than a";
while running
segmentation error (core dumped)
Working cod:=---- with the help of community
#include <stdio.h>
#include <malloc.h>
void main(){
int a,c;
char *b =(char *)malloc(100);
char string[100]="something";
b = &string;
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,*b);
printf("\n%s",b);
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x=y)
b = "both the values are equal";
else
b = "b is greater than a";
}
output:-
something
something
enter a and c:-
10
20
something
**
means still it is not updating the value in the function...
**
I fix your code in less than a minute.No warnings and probably works (I don't speaking for logical problems).This means that your warnings were common mistake that even an experienced engineer might do.However a smart engineer will use warnings to fix these warnings.
#include <stdio.h>
#include <malloc.h>
void find(int, int,char*);
int main(){
int a,c;
char *b = NULL;
char string[100]="something";
b = &string[0];
printf("\n %s \n\n %s",string,b);
printf("Enter a and c:-");
scanf("%d %d",&a,&c);
find(a,c,b);
printf("\n%s",b);
return 0;
}
void find(int x, int y,char *b){
if(x>y)
b = "a is greater than b";
else if(x == y)
b = "both the values are equal";
else
b = "b is greater than a";
}
If you check this , you will see that there is no warning now.
Regarding on your effort to learn , I would try to explain warnings and try to estimate and give you a big picture of what those warnings would result.
warning: return type of ‘main’ is not ‘int’
-Here you take the answers in why we prefer to return int in main.
int main vs void main
warning: suggest parentheses around assignment used as truth value
-This is the worst error you have. = is for asign , == is for comparison
Difference between = and ==
The other too errors ,
conflicting type
and
implicit declaration
means that preprocessor of your compiler reached function invocation ( find(a,c,*b); ) before the declaration of the function.So one compiler might fix that and auto resolve this while another compiler might have an error.That's why preprocessor check firstly the header file , but since you don't have a header file (that's bad) , you should have a declaration of the function before you invoke this.
Whilst you fix that you would receive a warning ,
warning: passing argument 3 of ‘find’ makes pointer from integer
without a cast
This means that you are trying to pass the pointer of the pointer. b was a pointer at the first place , which hold the address of the first element of your char array.So y should have pass this without *.
THIS is a very good example on the question Why we don't ignore error
.Because an error about implicit declaration of a function , led as to discover another error , more significant than the first , that was hiding under the first warning.
Another note is that you don't need to malloc there.You malloc when you want to allocate an amount of memory on the heap and keep it alive before you free it.
PS:I hope I help and I hope you also take some benefit out of these.If you have any question , do not hesitate to comment(better in chat , to avoid spam in the community)
Thank you.

function warnings C: "warning: type of ‘char_array’ defaults to ‘int’"

#include <stdio.h>
#include <string.h>
int myprint(char_array){
char mystring[80];
strcat(mystring, "\n");
printf("%s", mystring);
return 0;
}
int main(int argc, char** argv){
int count = 5;
char letter = 'c';
printf("decimal: %d, char: %c\n", count, letter);
myprint("sup");
return 0;
}
I get warnings on compile:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ compile basics.c basics
basics.c: In function ‘myprint’:
basics.c:4:5: warning: type of ‘char_array’ defaults to ‘int’
int myprint(char_array){
^
It compiles, but my myprint function doesn't work:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ ./basics
decimal: 5, char: c
I see this answer warning: return type defaults to ‘int’ [-Wreturn-type] but doesn't apply to me since I did declare int main(...)
I also see this declaration of functions:
return_type function_name( parameter list ) {
body of the function
}
And for myprint I declare as taking int and return 0. What does this warning mean and why doesn't my function work? Thank you
ANSWER:
void myprint(char mystring[]){
strcat(mystring, "\n");
printf("%s", mystring);
}
quiets the warnings, but causes Segmentation fault (core dumped)
Changing to
void myprint(char[] mystring){
strcat(mystring, "\n");
printf("%s", mystring);
}
makes it worse:
cchilders:~/projects/buildyourownlisp_in_C/ch3 [master]$ cc -std=c99 -Wall basics.c -o basics
basics.c:4:21: error: expected ‘;’, ‘,’ or ‘)’ before ‘mystring’
void myprint(char[] mystring;){
^
basics.c: In function ‘main’:
basics.c:15:5: warning: implicit declaration of function ‘myprint’ [-Wimplicit-function-declaration]
myprint("sup");
^
I also tried
void myprint(char[] mystring;){...
and
void myprint(char[] mystring,){...
As others have pointed out, you didn't specify a type for char_array, so it is assumed to be int. Changing it to char char_array[] fixes this.
Your other problem is that you're passing a string constant ("sup") to this function and are then attempting to modify it. String constants are stored in a read-only section of memory, so you can't modify it.
Given that you're only printing the string with a newline, you can do this instead:
void myprint(char mystring[]){
printf("%s\n", mystring);
}
You are not providing a data type for char_array in
int myprint(char_array)
You need char * or whatever you want it to be.
Firstly, function definitions should be like
return-type function-name ( parameter-type parameter-name, parameter-type parameter-name)
{ ... }
You did not specify either a parameter type or a parameter name. If you mean char_array to mean a type, you need to define it first, using a typedef or a struct or something else. If you mean char_array to be a parameter name, you need to specify its type, as
char[] char_array
say. Also, in this case, you do not actually use the variable char array anywhere in the function myprint. So the argument "sup" is not being used at all.
After edit to the question:
Try
char str[] = "sup";
myprint(str);
instead. As far as I know, you can't pass a string (a character array) by value.
int myprint(char_array)
What type has the parameter with name char_array? Because you didn't specify it, the compiler assumed it to be an int. Luckily it's warning you about that.
Don't rely on such behaviour, though. (I don't know whether this is still legal in C11 for example) Just write correct function declarations, including parameter types.
You need to specify the type of the parameters you expect to be passed to the function. There are mistakes in the function too. char_array is of char* type. You need to copy every part of the passed array to your local array, THEN only can you call printf for this function to work

Scanf Seg Fault

I'm working on my assignment for my C course, and I'm trying to take in the user's input and store it in a variable to use for later in my code. Here's what my main function looks like,
int main() {
// Variables here
char* inputLine[10];
do {
printf("Insert number....");
scanf("%s\n", inputLine);
// More stuff here
}
return 0;
}
This code gives me a bunch of warnings, warning: format specifies type 'char *' but the argument has type 'char **' [-Wformat], and if I change the variable declaration to,
char* inputLine = NULL;
When I execute my code I get a seg fault, can someone explain to me what I am doing wrong, and the differences of what happens in the memory when I'm initializing this variable?
char* inputLine[10];
--> is an array of ten pointers to char
printf's format %s expects argument of type char *, but you're providing it as type char **
Just use
char inputLine[10];
To avoid possible buffer overflow you should use
scanf("%9s", inputLine); //Notice the size with %s
9 only because C string are null terminated ('\0') so one extra byte for it goes at end
char inputLine[10];
do {
printf("Insert number....");
scanf("%9s\n", inputLine);
// More stuff here
} while( //some condition);
However if you edit your code and remove * you get answer, but normal array deprecated, nowdays, programmers use vector, normal array in C not safe :
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<string> inputLine;
You can define with every data type:
vector<int> myvar;
Or you can define multidimensional vector:
vector< vector <int> > myvar;

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