using letters in a Switch statement - c

I try to use Y and N in a switch statement but when I try to compile it I got an error what say " error: statement requires expression of integer type ('char [0]' invalid)
switch (xx) {
"
i also got a warning " warning: incompatible pointer to integer conversion passing 'char [1]' to parameter of type 'char' [-Wint-conversion]
sucheZeichen(name, imya); "
int main() {
char name[200];
printf("Please tell me your name:");
fflush(stdin);
scanf("%s", name);
printf("%s has %i letters\n", name, langeZeichne(name));
// frage
int end = 0;
char xx[0];
char imya[1];
do {
fflush(stdin);
printf("would you like to count a letter in %s (Y / N)?\n", name);
scanf("%c", xx);
switch (xx) {
case "Y":
printf("Please enter a letter\n");
scanf("%s", imya);
sucheZeichen(name, imya);
break;
case "N":
printf("Have a nice Day!");
end = 0;
break;
default:
printf("Wrong input\n");
break;
}
}while (end==0);
}

First of all, if you want to read a letter into xx don't use an array, and definitly not an array of size 0.
Second, your switch receive an char[] instead of a char.
Next, in the cases use chars instead of strings.
Moreover, according to the information in the question, sucheZeichen gets a char as a second parameter (or an int) so the same problem with xx as an array apply for imya as well.
Also, I added \n to the scanf so it won't read the newline character.
Your code should like like:
int main() {
char name[200];
printf("Please tell me your name:");
fflush(stdin);
scanf("%s", name);
printf("%s has %i letters\n", name, langeZeichne(name));
// frage
int end = 0;
char xx;
char imya;
do {
fflush(stdin);
printf("would you like to count a letter in %s (Y / N)?\n", name);
scanf("%c\n", &xx);
switch (xx) {
case 'Y':
printf("Please enter a letter\n");
scanf("%c\n", &imya);
sucheZeichen(name, imya);
break;
case 'N':
printf("Have a nice Day!");
end = 0;
break;
default:
printf("Wrong input\n");
break;
}
}while (end==0);
}

Related

passing argument 1 and 2 of ‘strcmp’ makes pointer from integer without a cast [-Wint-conversion]

Hello so I've been working a little prgramme which is sort of a calculator (I'm a beginner) and well as you can see in the tittle at then end of the code, the two if strcmp doesn't work. And vscode is telling me (for the strcmp) Exception has occurred. Segmentation fault. But gcc is telling me what is in the tittle.
#include <stdio.h>
#include <string.h>
int main()
{
float num1;
float num2;
float anwser;
int rnum = 1;
int hi = 0;
char operator;
char ifyorn;
char y = 'y';
char n = 'n';
while (hi == 0)
{
printf("Enter operator +, -, /, x: ");
scanf(" %c", &operator);
printf("Enter num %d :", rnum++);
scanf("%f", &num1);
printf("Enter num %d :", rnum++);
scanf("%f", &num2);
switch (operator)
{
case '+':
anwser = num1 + num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case '-':
anwser = num1 - num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case 'x':
anwser = num1 * num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
case '/':
anwser = num1 / num2;
printf("Do you want to continue y/n \n");
scanf(" %c", &ifyorn);
break;
default:
printf("This is not a valid character please try again :(");
break;
}
if(strcmp (ifyorn, n) == 0)
{
printf("%f", anwser);
hi == 1;
}
if(strcmp (ifyorn, y) == 0)
{
hi == 0;
}
}
}
The variables ifyorn, y and n are declared having the type char.
char ifyorn;
char y = 'y';
char n = 'n';
The function strcmp expects arguments of the pointer type char * that point to strings.
So these if statements
if(strcmp (ifyorn, n) == 0)
and
if(strcmp (ifyorn, y) == 0)
are incorrect. Instead you should write
if ( ifyorn == n )
and
if ( ifyorn == y )
Also instead of assignments you are using the comparison operator in these statements
hi == 1;
and
hi == 0;
You need to write
hi = 1;
and
hi = 0;
Increasing the variable rnum looks senseless
printf("Enter num %d :", rnum++);
scanf("%f", &num1);
printf("Enter num %d :", rnum++);
scanf("%f", &num2);
Why not just to write
printf("Enter num %d :", 1 );
scanf("%f", &num1);
printf("Enter num %d :", 2 );
scanf("%f", &num2);
And in the code snippet under the label default you should add one more statement
default:
printf("This is not a valid character please try again :(");
ifyorn = y;
break;
You don't have to be mean to the guy ,he is learning.
You are getting this error because you are passing characters to strcmp() instead of pointers to characters.
Here is more information regarding that function.
https://www.programiz.com/c-programming/library-function/string.h/strcmp

Why does scanf read garbage?

I'm trying to write a program that allows to add data about different types of stars and print them back on the screen. Why does this not work:
typedef union{
struct{
char name_main[30];
int age;
char color[12];
};
struct{
char name_binary[30];
double radius_1, radius_2;
};
struct{
char name_light[30];
double luminosity_low, luminosity_high, period;
};
}STARS;
int main(int argc, char **argv)
{
bool running = true;
int choice;
STARS *star = (STARS *)malloc(sizeof(star));
printf("Star Menu\n");
putchar('\n');
while(running)
{
putchar('\n');
printf("Please choose a type of star:\n");
printf("1. Main Sequence Star\n2. Binary Star\n3. Variable Light Star\n4. Exit\n");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("You've chosen: Main Sequence Star\n");
printf("Please enter the name of the star:\n");
scanf("%s", star->name_main);
//printf("%s", star->name_main);
printf("Please enter the age of: %s\n", star->name_main);
scanf("%d", &star->age);
printf("Age: %d\n", star->age);
printf("Please enter the color of: %s\n", star->name_main);
scanf(" %s", star->color);
printf("Color: %s\n", star->color);
// printf("Type : Main sequence | Name : %s | Age : %d | Color : %s\n", star->name_main, star->age, star->color);
break;
case 2:
printf("You've chosen: Binary Star\n");
printf("Please enter the name of the star:\n");
scanf("%s", star->name_binary);
printf("Name: %s\n", star->name_binary);
printf("The radius of the first star:\n");
scanf("%lf", &star->radius_1);
printf("The radius of the second star:\n");
scanf("%lf", &star->radius_2);
printf("Radius 1: %.2lf | Radius 2: %.2lf\n", star->radius_1, star->radius_2);
break;
case 3:
printf("You've chosen: Variable Light Star\n");
break;
case 4:
printf("Exit\n");
running = false;
break;
}
}
return 0;
}
I'm using a union of structs because each star has specific characteristics and we don't care about the others' when we write for a certain type. The issue appears at the color, if I write red the output will be: Color: r:. I've tried adding a space before the format specifier, consuming a character before using scanf but the issue persists and I'm not sure why. Any thoughts?
You didn't allocate enough size of buffer. sizeof(star) is the size of the pointer. A pointer is typically 4-byte or 8-byte long, but the structure is at least 30-byte long for char name_main[30];.
Also note that casting results of malloc() family is considered as a bad practice.
Wrong line:
STARS *star = (STARS *)malloc(sizeof(star));
It should be:
STARS *star = malloc(sizeof(*star));
STARS *star = (STARS *)malloc(sizeof(star));
It's a mistake. sizeof(star) returns size of the pointer, not the structure.
Change it to: STARS *star = (STARS *)malloc(sizeof(*star)); to fix your problem.

scanf and switch statement debug

All the cases work except the switch 'a' case. The a case runs the insert method below. Any help would be appreciated, thanks. printf statements inside the switch statement don't work.
void insert() {
char name;
printf("enter your name");
scanf("%c", &name);
for(int i = 0; i < LENGTH; i++){
if (!Thesame(names[1], name) == 0 && counter != LENGTH && strlen(name) <= MAX){
for(int j = 0; j < LENGTH; j++){
strcpy(names[counter],name);
}
}
else{
printf("error");
}
}
```
int main() {
while (1) {
char input;
printf("Type in 'a' be added to the system \n");
printf("Type in 'n' to print next patient and remove from
waitlist \n");
printf("Type in 'l' to list the patients on the waitlist \n");
printf("Type in 'q' to quit the program \n");
scanf("%c", &input);
switch (input) {
case 'a':
insert();
break;
case 'n':
next();
break;
case 'l':
print();
break;
case 'q':
return 0;
}
}
}
char name;: name can contain only a single character. So when you type for example: cuq, name will contain c, then insert does whatever with name and then returns to main. Then in main scanf("%c", &input) will read the remaining characters from the input buffer ('u' and 'q') and because of case 'q': the programs stops. Use a debugger or put some printfs at strategic places in your code to see what happens.
You want a string here and you probably want something like this in insert:
char name[100];
printf("enter your name: ");
scanf("%s", name);
...
You also probably need to change the Thesame function.

C language - strcmp returns 0 always and strcpy not copying the string in another array

I want to run this code where I enter two strings and user put the option for performing the following task.
After I enter 'a' in the menu, the statement strcpy(s_1,s_2); the string is copied to s_1 but when I added
#include <string.h>
it asked me to use strcpy_s() which I did and code stopped working.
When I enter 'b' in the menu, I get only one output
Both Strings are equal to each other
I don't understand why strcmp() returns 0 always.
It would be great if someone help me out in this issue.
By the way I'm using Visual Studio 2015 for compiling my C code.
#include< stdio.h>
#include< string.h>
#include< stdlib.h>
#include< process.h>
//USER-DEFINED FUNCTIONS
char top_down();
char copy_function();
char compare_function();
//char adder_function();
void header(void);
#define MAX 1000
void header()
{
printf("*-*-*-*-*TASK_PERFORMER*-*-*-*-*");
printf("\n\n");
}
//PROGRAM STARTS HERE
main()
{
//VARIABLE DECLARATION
char x =
{ 0 };
//HEADING FUNCTION
header();
//USER-DEFINED FUNCTION CONSISTING OF ALL INPUTS.
top_down();
//TERMINAL-PAUSE
system("pause");
}
char top_down()
{
char s1[MAX] =
{ 0 }, s2[MAX] =
{ 0 }, x =
{ 0 };
printf("Enter the First String : \n");
fgets(s1, MAX, stdin);
printf("\n");
printf("The Entered First String : \n");
printf("%s", s1);
printf("\n");
printf("Enter the Second String : \n");
fgets(s2, MAX, stdin);
printf("\n");
printf("The Entered Second String : \n");
printf("%s", s2);
printf("\n");
printf("*-*-*-TYPE ANY OPTION TO PERFORM TASK-*-*-*");
printf("\n");
//GIVEN OPTIONS FOR SELECTOR
printf("Enter one option from the following : \n\n");
printf("(a) To Copy one string to another. \n");
printf("(b) To Compare two string. \n");
printf("(c) To Add a string to the end of another string. \n");
printf("\n");
repeat:
printf("Enter Your Option : \n");
scanf_s("%c", &x);
printf("\n");
//OPTION-SELECTOR
switch (x)
{
case 'a':
copy_function(s1, s2);
break;
case 'b':
compare_function(s1, s1);
break;
case 'c':
//adder_function(s1, s2);
break;
default:
printf("INVALID OPTION \n");
printf("Please Try Again \n");
goto repeat;
break;
return;
}
}
char copy_function(char s_1[], char s_2[])
{
int x = 0;
x = strlen(s_2);
printf("Second String will be copied to First string now \n");
//strcpy(s_1, s_2);
strcpy_s(s_1, x, s_2);
printf("\n");
printf("First String Output : \n");
printf("%s", s_1);
return;
}
char compare_function(char s_1[], char s_2[])
{
int a = 0, l1 = 0, l2 = 0, i = 0;
printf("First String will be compared to Second String now \n ");
//printf("\n");
if (strcmp(s_1, s_2) == 0)
printf("Both String are equal to each other \n");
else if (strcmp(s_1, s_2) > 0)
printf("First String is greater than Second String");
else
printf("First String is lesser than Second String \n");
return;
}
Not sure if your program is in progress. I modified it and removed anything I thought was not necessary.
The functions' signatures change to void
Removed x in main
Return type of main set to int (It is int by default, but this spares you the warning of the compiler)
I work on Linux, so I removed the system(...), feel free to add it.
Only left variables declarations in top_down (not important, but an initial value should have a meaning and in your case there is no meaning to 0)
Changed scanf_s("%c", &x); to scanf(" %c", &x); (note the space. not sure if on windows that makes a difference. please check.)
Changed the function call compare_function(s1, s1); to compare_function(s1, s2);
Removed the return statements in the void functions
In copy_function I removed int x = 0; and x = strlen(s_2);
In copy_function I changed strcpy_s(s_1, x, s_2); to strcpy(s_1, s_2);
In compare_function I removed int a = 0, l1 = 0, l2 = 0, i = 0;
You use label/goto. That's ok, but considered not cool nowadays. You could use a loop and break in case of an invalid option.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//USER-DEFINED FUNCTIONS
void top_down();
void copy_function();
void compare_function();
//char adder_function();
void header(void);
#define MAX 1000
void header() {
printf("*-*-*-*-*TASK_PERFORMER*-*-*-*-*");
printf("\n\n");
}
//PROGRAM STARTS HERE
int main() {
//HEADING FUNCTION
header();
//USER-DEFINED FUNCTION CONSISTING OF ALL INPUTS.
top_down();
return 0;
}
void top_down() {
char s1[MAX], s2[MAX], x;
printf("Enter the First String : \n");
fgets(s1, MAX, stdin);
printf("\n");
printf("The Entered First String : \n");
printf("%s", s1);
printf("\n");
printf("Enter the Second String : \n");
fgets(s2, MAX, stdin);
printf("\n");
printf("The Entered Second String : \n");
printf("%s", s2);
printf("\n");
printf("*-*-*-TYPE ANY OPTION TO PERFORM TASK-*-*-*");
printf("\n");
//GIVEN OPTIONS FOR SELECTOR
printf("Enter one option from the following : \n\n");
printf("(a) To Copy one string to another. \n");
printf("(b) To Compare two string. \n");
printf("(c) To Add a string to the end of another string. \n");
printf("\n");
repeat:
printf("Enter Your Option : \n");
scanf(" %c", &x);
printf("\n");
//OPTION-SELECTOR
switch (x) {
case 'a':
copy_function(s1, s2);
break;
case 'b':
compare_function(s1, s2);
break;
case 'c':
//adder_function(s1, s2);
break;
default:
printf("INVALID OPTION \n");
printf("Please Try Again \n");
goto repeat;
break;
}
}
void copy_function(char s_1[], char s_2[]) {
printf("Second String will be copied to First string now \n");
strcpy(s_1, s_2);
printf("\n");
printf("First String Output : \n");
printf("%s", s_1);
}
void compare_function(char s_1[], char s_2[]) {
printf("First String will be compared to Second String now \n ");
if (strcmp(s_1, s_2) == 0)
printf("Both String are equal to each other \n");
else if (strcmp(s_1, s_2) > 0)
printf("First String is greater than Second String");
else
printf("First String is lesser than Second String \n");
}

scanf is skipped even if using fflush

I have a scanf that doesn't accept input. The value is automatically zero, even if the variable wasn't initialized. The scanf is skipped:
printf("\nEnter the number of the student to be dropped: ");
fflush(stdin);
scanf(" %d ",&choice);
printf("choice is %d", choice);
When the program is run, it immediately displays "choice is 0".
The snippet above is taken from the drop() function in this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student{
char name[50];
char* course;
};
main()
{
char repeat;
do{
system("cls");
int mainchoice;
printf("Student Enrollment System");
printf("\n");
printf("\n");
printf("1. View\n");
printf("2. Enroll\n");
printf("3. Drop enrollment\n");
printf("Select choice: ");
fflush(stdin);
scanf("%d",&mainchoice);
system("cls");
switch(mainchoice){
case 1:
view();
break;
case 2:
enroll();
break;
case 3:
drop();
break;
default:
printf("Please enter a valid number.");
getch();
fflush(stdin);
break;
}
printf("\nWould you like to make another transaction? [Y/N]: ");
fflush(stdin);
scanf("%c",&repeat);
}while(repeat=='Y'||repeat=='y');
}
view(){
int ctr = count();
printf("Enrolled Students:\n\n");
system("type records.txt");
printf("\n\nNumber of students enrolled: %d", ctr);
getch();
fflush(stdin);
}
enroll(){
int choice;
char validate;
printf("1. Information Technology\n");
printf("2. Computer Science\n");
printf("3. Computer Engineering\n");
printf("4. Information Systems\n");
struct student news;
printf("Name: ");
fflush(stdin);
gets(news.name);
printf("Course Number: ");
fflush(stdin);
scanf("%d", &choice);
switch(choice){
case 1:
news.course = "BSIT";
break;
case 2:
news.course= "BSCS";
break;
case 3:
news.course = "BSCpE";
break;
case 4:
news.course = "BSIS";
break;
default:
printf("Please enter a valid number\n");
break;
}
printf("Enroll %s to %s? [Y/N]:",news.name,news.course);
fflush(stdin);
scanf("%c", &choice);
if(choice=='Y' || choice=='y')
{
FILE * records;
records = fopen("records.txt", "a+");
fprintf(records, "%s, %s\n",news.name,news.course);
fclose(records);
printf("%s has been enrolled to %s\n",news.name, news.course);
}
else
{
printf("You have chosen to cancel your transaction");
}
}
drop(){
printf("Drop Student:\n\n");
int ctr = 0;
int choice; //which student to delete
char c;
FILE * record; // original records.txt
FILE* repo; //temporary data storage
record = freopen("records.txt", "r", stdin);
while((c = fgetchar())!=EOF){
if(c == '\n'){
}
else{
ctr=ctr+1;
printf("%d. ", ctr);
while(1){
printf("%c",c);
c= fgetchar();
if(c=='\n'){
printf("%c",c);
break;
}
}
}
}
fclose(record);
fflush(stdin);
fflush(stdin);
printf("\nEnter the number of the student to be dropped: ");
fflush(stdin);
scanf(" %d ",&choice);
getch();
getch();
fflush(stdin);
ctr = 1;
fflush(stdin);
repo = fopen("temp.txt","w");
record = freopen("records.txt","r",stdin);
while((c = getchar()) != EOF){
if(c == '\n'){
}
else{
while(ctr!=choice){
fprintf(repo,"%c",c);
c= fgetchar();
if(c=='\n'){
fprintf(repo,"%c",c);
ctr = ctr + 1;
break;
}
}
}
}
fclose(record);
fclose(repo);
getch();
}
//counts the number of rows in the record
int count(){
int ctr=0;
char c;
FILE * records;
records = freopen("records.txt","r", stdin);
if(records!=NULL){
while((c=fgetchar()) !=EOF){
if(c=='\n'){
ctr = ctr+1;
}
}
}
fclose(records);
return ctr;
}
Doing fflush doesn't seem to help. Any ideas?
The behavior of fflush is not defined for input streams; fflush(stdin) is a coding error, and you should remove those calls from your code.
When scanning for individual characters, add a blank space before the %c conversion specifier; this will tell scanf to skip any leading whitespace and read the next non-whitespace character:
scanf(" %c", &choice);
The %d and %s conversion specifiers will skip over any leading whitespace.
Edit
Implicit typing is no longer supported as of C99, and it's a bad habit to get into. Explicitly type your functions, and use void as the parameter list to specify that they take no arguments:
main() => int main(void)
view() => void view(void) // void since it isn't returning a value
drop() => void drop(void)
etc.
Similarly, gets was deprecated in C99 and is gone completely as of the 2011 standard. Using it will introduce a point of failure / major security hole in your program. Use fgets instead.

Resources