I am creating a simple system for people to enter there basic details, have them printed on the screen and once confirmed writen to a text file, is the info is wrong the user enters edit ot be looped back to the beginning of the report and if another input is ented it asks the question again. Im a struggling to get the print to file to work and the two end loops.
#include <stdio.h>
#include <string.h>
int get_line(const char *prompt, char *dest, size_t size) {
printf("%s", prompt);
fflush(stdout);
if (fgets(dest, size, stdin) == NULL) {
dest[0] = '\0';
return 0;
}
dest[strcspn(dest, "\n")] = '\0'; // Lop off potential trailing '\n'
return 1;
}
int main(void)
{
char first_name[20], surname[20], street_no[10], street_name[40], postcode[10], contact_no[20], save_edit_qu[10];
int dd, mm, yy;
get_line(" Enter first name:\n", first_name, sizeof first_name);
get_line(" Enter surname:\n", surname, sizeof surname);
get_line(" Contact Number\n", contact_no, sizeof contact_no);
get_line(" Street Number\n", street_no, sizeof street_no);
get_line(" Street Name\n", street_name, sizeof street_name);
get_line(" Postcode\n", postcode, sizeof postcode);
printf(" First Name : %s\n", first_name);
printf(" Surname : %s\n", surname);
printf(" Contact No.: %s\n", contact_no);
printf(" Street No. : %s\n", street_no);
printf(" Stret Name : %s\n", street_name);
printf(" Postcode : %s\n", postcode);
get_line(" If the informations above is correct please enter SAVE/if you wish to change any informations please enter edit", save_edit_qu, sizeof save_edit_qu);
if (save_edit_qu[0] == 'SAVE' || save_edit_qu[0] == 'save') {
//write info to file
}
if (save_edit_qu[0] == 'EDIT' || save_edit_qu[0] == 'edit') {
//loop back to beginning of report
}
else if ()//loop to beginning of SAVE/EDIT QU
return 0;
}
use strcmp() and use double quotes "" for string !
if (strcmp(save_edit_qu,"SAVE") == 0 || strcmp(save_edit_qu,"save") == 0) {
or test only first character using single quotes like this
if (save_edit_qu[0] == 'S' || save_edit_qu[0] == 's') {
So, there are a couple of things wrong about your program. I'll try to cover them all here before I show you the changes.
Your string comparison is simple nonsensical: save_edit_qu[0] == 'SAVE' simply compares the first character/byte of save_edit_qu to 'SAVE', which itself isn't a proper string literal. You've got to enclose string literals in double quotes in C. And even if you did do that here, it doesn't make sense to compare a character to a string. What you should do is use strcmp from string.h to do the comparison for you. I've placed that inside my fixed version of your program. The format is: strcmp(a,b) == 0 if string a is equal to string b.
You're giving users the ability to edit all their input data. Therefore, you should be placing your data collection in a loop. This allows you to constantly re-collect the data as long as the user isn't done.
do {
// collect data.
} while (!done);
Finally, you're having users perform an action within the data collection loop so that they can choose what they'd like to do with the data. They can either edit, or save. There's also the case they enter neither. In this case, they'll be prompted again. This warrants another control loop inside.
do {
// collect data
do {
// save or edit
} while (!validChoice);
} while (!done);
With this said, here is the working program. I have not implemented the writing-to-file portion for you though. I think you can give that a shot yourself!
#include <stdio.h>
#include <string.h>
int get_line(const char *prompt, char *dest, size_t size) {
printf("%s", prompt);
fflush(stdout);
if (fgets(dest, size, stdin) == NULL) {
dest[0] = '\0';
return 0;
}
dest[strcspn(dest, "\n")] = '\0'; // Lop off potential trailing '\n'
return 1;
}
int main(void)
{
char first_name[20], surname[20], street_no[10], street_name[40], postcode[10], contact_no[20], save_edit_qu[10];
int dd, mm, yy, done = 0;
// Data collection loop: Runs as long as the user opts to edit the data.
do {
// Fetch data.
get_line(" Enter first name:\n", first_name, sizeof first_name);
get_line(" Enter surname:\n", surname, sizeof surname);
get_line(" Contact Number\n", contact_no, sizeof contact_no);
get_line(" Street Number\n", street_no, sizeof street_no);
get_line(" Street Name\n", street_name, sizeof street_name);
get_line(" Postcode\n", postcode, sizeof postcode);
printf(" First Name : %s\n", first_name);
printf(" Surname : %s\n", surname);
printf(" Contact No.: %s\n", contact_no);
printf(" Street No. : %s\n", street_no);
printf(" Stret Name : %s\n", street_name);
printf(" Postcode : %s\n", postcode);
// Action loop: Runs as long as no valid input is given.
do {
get_line(" If the informations above is correct please enter SAVE/if you wish to change any informations please enter edit\n", save_edit_qu, sizeof save_edit_qu);
// Option to quit.
if (strcmp(save_edit_qu, "SAVE") == 0 || strcmp(save_edit_qu, "save") == 0) {
fprintf(stdout, "Writing data to file...\n");
// write data here.
// Set done flag, and exit action loop.
done = 1;
break;
}
// Option to edit.
if (strcmp(save_edit_qu, "EDIT") == 0 || strcmp(save_edit_qu, "edit") == 0 ) {
//loop back to beginning of report
break;
}
// Otherwise ask prompt again ^.
} while (1);
} while (!done);
return 0;
}
Related
Problem:
A program that will ask an input of an employee data in this format:
ID, firstname_lastname, rate, address, position
Example:
001-111, Juan_DelaCruz, 2, Nasipit Agusan del Norte, Manager
Let Salary rate be equivalent to: 1=250, 2=300, 3=350, 4=375
From the input above, it will display like this:
Employee:001-111
First Name: Juan
Last Name: Dela Cruz
Salary rate: 300
Address: Nasipit Agusan del Norte
Position: Manager
I want the salary rate to automatically display its corresponding equivalent value based on the metric set above. I'm trying to figure out how to manipulate the strings so that whatever the result from string 'rate' will be passed on to string 'sal' with its value. Any inputs will be appreciated!
#include <stdio.h>
#include <string.h>
int main () {
char *empdata[100];
char *id, *fname, *lname, *rate, *add, *posi;
printf("Employee data format: ID, firstname_lastname, rate, address, position");
printf("\nEmployee data example: 001-111, Juan_DelaCruz, 2, Nasipit Agusan del Norte, Manager");
printf("\nLet Salary rate be equivalent to: 1=250, 2=300, 3=350, 4=375");
printf("\n\nEnter your data: ");
gets(empdata[100]);
id=strtok(empdata[100], ",");
fname=strtok(NULL, "_");
lname=strtok(NULL, ",");
rate=strtok(NULL, ",");
add=strtok(NULL, ",");
posi=strtok(NULL, ",");
char sal1[5]="250", sal2[5]="300", sal3[5]="350", sal4[5]="375";
char sal[3];
if (strncmp(rate,"1", 1) == 0) {
strcpy(sal[3],sal1[5]);
} else if (strncmp(rate,"2", 1) == 0) {
strcpy(sal[3],sal2[5]);
} else if (strncmp(rate,"3", 1) == 0) {
strcpy(sal[3],sal3[5]);
} else if (strncmp(rate,"4", 1) == 0) {
strcpy(sal[3],sal4[5]);
}
printf("\n\nHere's your employee data from the input above: ");
printf("\n\nEmployee: %s", id);
printf("\nFirst Name: %s", fname);
printf("\nLast Name: %s", lname);
printf("\nSalary Rate: %s", sal[3]);
printf("\nAddress: %s", add);
printf("\nPosition: %s", posi);
return 0;
}
In the code there are 2 problems:
The strings declaration is wrong.
In C strings are made by the actual characters and \0 (\0 is the string terminator).
In your code you declarated 4 strings, each one is a char[5] meaning it can contain 5 chars (4 characters + \0), the string in which you want to copy the values is a char[3] meaning it can contain only 3 chars ( 2 characters + \0).
They arent compatible because in your scenario you are trying to copy a string of 3 characters + \0 to a string that can contain only 2 characters + \0.
For example ,from your code, sal1[5]="250" in reality is "250\0" using 4/5 chars
The correct declaration would be:
char sal1[5]="250", sal2[5]="300", sal3[5]="350", sal4[5]="375";
char sal[5];
The strcpy parameters are wrong.
In C strcpy() needs two parameters: char* destination and char* source, as you can see they both are char pointers.
The pointers have to be pointers to the first element of the string because the functions copies the string starting from the pointer you gave as parameter to the terminator \0.
In your code you wrote as parameter sal[3] and sal[5] wich are the last elements of the two strings. This leads to a lot of errors.
The right use of strcpy() in your code is:
strcpy(&sal[0],&sal1[0]);
//or
strcpy(sal,sal1);
Also, not raleted to the question, the printf at the end is wrong for the same motivation.
The correct version is:
printf("\nSalary Rate: %s", sal);
I hope my anser was useful.
Sorry if i said something wrong, i'm kind of a new user and english is not my first language.
Note the space after the comma in the sample input...
001-111, Juan_DelaCruz, 2, Nasipit Agusan del Norte, Manager
Post rate=strtok(NULL, ",");, rate contains two characters, space and '2', terminated by '\0'.
Later, when performing a strncmp you have to accommodate for this....
An example would be...
(strncmp(rate," 2", 2) == 0);
I am sure you will figure more robust implementations, as time goes by...
Here is my version, with minimal changes to the current implementation.
Please see the comments.
int main () {
//char *empdata[100]; /* declares "empdata" as array[100] of pointers to char.*/
char empdata[100]; /* declares "empdata" as array[100] of characters */
char *id, *fname, *lname, *rate, *add, *posi;
printf("Employee data format: ID, firstname_lastname, rate, address, position");
printf("\nEmployee data example: 001-111, Juan_DelaCruz, 2, Nasipit Agusan del Norte, Manager");
printf("\nLet Salary rate be equivalent to: 1=250, 2=300, 3=350, 4=375");
printf("\n\nEnter your data: ");
//gets(empdata[100]); /* the gets function was officially removed from C`s \
2011 international standard \
use fgets(char *s, int n, FILE * stream); \
fgets returns 's' or NULL if EOF or error occurs */
fgets(empdata,100,stdin);
//id=strtok(empdata[100], ","); /* strtok expects a character pointer */
id=strtok(empdata, ","); /* "empdata" is the "address of/points to" the first \
element of the array*/
//Have made similar changes to the calls to strcpy and printf
fname=strtok(NULL, "_");
lname=strtok(NULL, ",");
rate=strtok(NULL, ",");
add=strtok(NULL, ",");
posi=strtok(NULL, ",");
char sal1[5]="250", sal2[5]="300", sal3[5]="350", sal4[5]="375";
//char sal[3]; /* make sure to map the array sizes when copying \
will ensure that the '\0' terminator is copied as well */
char sal[5];
if (strncmp(rate," 1", 2) == 0) {
strcpy(sal,sal1);
} else if (strncmp(rate," 2", 2) == 0) {
strcpy(sal,sal2);
} else if (strncmp(rate," 3", 2) == 0) {
strcpy(sal,sal3);
} else if (strncmp(rate," 4", 2) == 0) {
strcpy(sal,sal4);
}
printf("\n\nHere's your employee data from the input above: ");
printf("\n\nEmployee: %s", id);
printf("\nFirst Name: %s", fname);
printf("\nLast Name: %s", lname);
printf("\nSalary Rate: %s", sal);
printf("\nAddress: %s", add);
printf("\nPosition: %s", posi);
return 0;
}
I created a file and filled it with some entries. However, I want to read this file and show it on the screen. Also, after showing the entries, I want it to be deleted with my permission. But I am stuck at this point please help me.
EDIT: Code is updated but still couldn't figure it out how to do :/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char name[20], surname[20], city[30], country[30], gender[15];
int count = 0;
int main() {
FILE *f1;
f1 = fopen("C:\\FurkanArslan.txt", "r+");
while (count < 10) { // every step provides 5 new data, so 5*10 will provide 50 data in total.
printf("\n*Please enter required information: \n");
printf("Name :"); scanf("%s", name);
printf("Surname:"); scanf("%s", surname);
printf("Country:"); scanf("%s", country);
printf("City :"); scanf("%s", city);
printf("Gender :"); scanf("%s", gender);
fprintf(f1, " %s | %s | %s | %s | %s\n\n", name, surname, gender, city, country);
count++;
}
fclose(f1);
printf("\n<<<<<%d data has been successfully saved!>>>> \n", count * 5);
printf("-------------------------------------\n");
f1 = fopen("C:\\FurkanArslan.txt", "r");
char c, answer;
while ((c = fgetc(f1)) != EOF)
putchar(c); // In this part I displayed file on the screen.
printf("\n\n <<<< %d entries are displayed on the screen! >>>>", count * 5);
printf("\n\nWould you like to remove your file [Y/N] ?");
scanf(" %c", &answer);
if (answer == 'y' || answer == 'Y') {
remove("f1");
printf("\n\n***File successfully removed!");
}
return 0;
}
In order to show the content of a file you have to open it and read it letter by letter, after that, you can use the putchar function to output the current character
FILE *fp = fopen("path/to/file.txt","r");
char c;
while((c=fgetc(fp))!=EOF)
putchar(c);
fclose(fp);
after that to remove a file you need to use the remove function, which receives the name of the file as paramter.
remove("my_file.txt");
There are multiple issues in your code:
there is no need to make the variables and arrays global, just define them in the body of the main() function.
you should tell scanf() the maximum number of characters to store in the destination array with a length specifier in the format string (eg: "%19s") and check for conversion success.
the variable c used in the reading loop must have type int for proper detection of EOF. fgetc() returns a positive byte value if successful and the special negative value EOF at end of file.
you do not need to reopen the file after writing to it. Sine you opened it for update mode, you can just seek back to the beginning of the file with rewind(f1) or fseek(f1, 0L, SEEK_SET).
the file is open for read and update mode ("r+"): it will fail if the file does not exist. You should open it in write and update mode with "w+" to create or truncate it.
you should check that fopen succeeds at opening the file, otherwise you invoke undefined behavior passing a null stream pointer to fprintf.
to remove the file, remove() takes the filename as its argument. You must close the file before attempting to remove it.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
const char *filename = "C:\\FurkanArslan.txt";
char name[20], surname[20], city[30], country[30], gender[15];
int count = 0;
FILE *f1 = fopen(filename, "w+");
if (f1 == NULL) {
printf("Cannot open file %s.\n", filename);
return 1;
}
while (count < 10) { // every step provides 5 new data, so 5*10 will provide 50 data in total.
printf("\n*Please enter required information: \n");
printf("Name :"); if (scanf("%19s", name) != 1) break;
printf("Surname:"); if (scanf("%19s", surname) != 1) break;
printf("Country:"); if (scanf("%29s", country) != 1) break;
printf("City :"); if (scanf("%29s", city) != 1) break;
printf("Gender :"); if (scanf("%14s", gender) != 1) break;
fprintf(f1, " %s | %s | %s | %s | %s\n\n", name, surname, gender, city, country);
count++;
}
printf("\n<<<<< %d data has been successfully saved to %s! >>>>\n",
count * 5, filename);
printf("-------------------------------------\n");
rewind(f1);
int c;
while ((c = fgetc(f1)) != EOF)
putchar(c);
printf("\n\n <<<< %d entries are displayed on the screen! >>>>\n", count);
fclose(f1);
printf("\nWould you like to remove your file [Y/N] ?");
char answer;
if (scanf(" %c", &answer) == 1 && (answer == 'y' || answer == 'Y')) {
if (remove(filename)) {
printf("\n\n***Error removing file %s: %s\n",
filename, strerror(errno));
} else {
printf("\n\n***File %s successfully removed!\n", filename);
}
}
return 0;
}
I am new to C. I allocated memory with this statement:
patientptr = (char*) calloc (118, sizeof (char));
then I assign data using this (this is a part of the function):
char name[51];
int age;
char agestr[3];
char infectiondate [11];
char address[51];
char *patientptr;
printf("\nEnter the patient name (50 characters at maximum): ");
scanf ("%50s", name);
*patientptr = name;
printf("Enter the patient age: ");
scanf ("%d", &age);
sprintf (agestr, "%2d", age);
*(patientptr + 51) = agestr;
printf("Enter the patient date of infection (in form of dd/mm/year): ");
*(patientptr + 54) = scanf ("%10d", infectiondate);
printf("Enter the patient address (50 characters at maximum): ");
*(patientptr + 65) = scanf ("%50s", address);
*(ptrsptr+patientsnum-1) = patientptr;
printf ("\nPatient added.\n");
Everything goes fine except that after the "enter the patient address: " line, it prints the "patient added" line directly without waiting to scan the address. the output is like this:
Enter the patient name (50 characters at maximum): ahmed
Enter the patient age: 20
Enter the patient date of infection (in form of dd/mm/year): 10/10/2020
Enter the patient address (50 characters at maximum):
Patient added.
is the wrong with my allocated memory?
You may well have used calloc to allocate some memory but examine this snippet:
char *patientptr;
printf("\nEnter the patient name (50 characters at maximum): ");
scanf ("%50s", name);
*patientptr = name;
That first line shadows whatever patientptr was with an uninitialised pointer, hence the final line is undefined behaviour (patientptr now points to some arbitrary address). All bets are off at this point, anything is possible.
Fix that and try again.
In addition, it looks like you believe that:
*(patientptr + 51) = agestr;
is a way to copy a C string from one place to another. In actual fact, this will attempt to place the agestr pointer value into the single character at the memory location &(patientptr[51]), and possibly should have warned you about this.
You need to look into strcpy for this, something along the lines of:
strcpy(patientptr + 51, agestr);
But, if you're looking to do user input, it's often a good idea to work around the limits of scanf. It does, after all, stand for "scan formatted" and there's very little that's less formatted than user input.
I have a favourite function I use for this, which is shown below, along with the modifications to your own code to use it (using both that function and with quite a bit of other validation specific to your case):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// Bullet-proof line input function.
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
// Ensure a character array is non-empty and all digits.
int checkDigits(char *arr, size_t sz) {
if (sz == 0) {
return 0;
}
while (sz-- > 0) {
if (! isdigit(*arr++)) {
return 0;
}
}
return 1;
}
// Get customer data line, return NULL if okay, error if not.
// Output record must be long enough for format string below
// and a one-character end-string marker.
static char *getPatientData(char *patientData) {
// Keep this format string in sync with field sizes below.
static char *fmtString = "%-50.50s" "%3d" "%-10.10s" "%-50.50s";
char name[51];
char ageStr[4];
char infectionDate[11];
char address[51];
if (getLine("Patient name: ", name, sizeof(name)) != OK) {
return "Error getting name.";
}
if (getLine("Patient age: ", ageStr, sizeof(ageStr)) != OK) {
return "Error getting age.";
}
if (! checkDigits(ageStr, strlen(ageStr))) {
return "Error, age contains non-digit data.";
}
int age = atoi(ageStr);
// Further age sanity checking, if desired. Example: ensure <= 150.
if (getLine("Infection date (dd/mm/yyyy): ", infectionDate, sizeof(infectionDate)) != OK) {
return "Error getting infection date.";
}
if (
strlen(infectionDate) != 10
|| infectionDate[2] != '/'
|| infectionDate[5] != '/'
|| ! checkDigits(infectionDate, 2)
|| ! checkDigits(infectionDate + 3, 2)
|| ! checkDigits(infectionDate + 6, 4)
) {
return "Error, incorrect format.";
}
// Further checking if desired. Example: valid year/month/day combo.
if (getLine("Patient address: ", address, sizeof(address)) != OK) {
return "Error getting address.";
}
sprintf(patientData, fmtString, name, age, infectionDate, address);
return NULL;
}
int main(void) {
char *patientPtr = malloc (50 + 3 + 10 + 50 + 1);
char *result = getPatientData(patientPtr);
if (result != NULL) {
printf("*** %s\n", result);
return 1;
}
printf("Got '%s'\n", patientPtr);
return 0;
}
A sample run follows:
Patient name: Pax Diablo
Patient age: 55
Infection date (dd/mm/yyyy): 25/05/2020
Patient address: No fixed abode
Got 'Pax Diablo 5525/05/2020No fixed abode '
I want to enter multiple printfs but i dont get opportunity to enter.
I can enter only 1, but after that it just ends the programme.I tried with do while but it didnt work
int main()
{
int number;
char username[30]="";
char fullName[30]="";
char password[30]="";
printf("Do you want to log in(1) or register (2)? \n");
scanf("%d",&number);
if (number==2)
{
printf("username : ");
scanf("%s",&username);
printf("Full name : ");
scanf("%s",&fullName);
printf("Password : ");
scanf("%s",&password);
printf("Repeat password : ");
scanf("%s",&password);
}
return 0;
}
Read full lines using fgets() into a suitably large buffer, then parse that.
Note that %s will stop at the first blank character, so a full name of "Mr X" will leave "X" in the input buffer, grabbing that for the password and so on. It's really not a robust way of getting input.
I can enter only 1, but after that it just ends the programme.
Of course, as the code has if (number==2) #Scadge
If you enter "2", consider the following:
scanf("%s",&fullname); will not save spaces or other white-spaces into fullname. Entering a full name like "John Doe" will save "John" into fullname and "Doe" into password.
Avoid using scanf().
Rather than use scanf() to read user input, read user input with fgets(). This is a fine opportunity for helper functions that can handle various input issues.
int read_int(const char *prompt) {
if (prompt) fputs(prompt, stdout);
fflush(stdout); // insure output is written before asking for input
char buffer[40];
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return NULL;
}
int i;
if (sscanf(buffer, "%d", &i) == 1) {
return i;
}
// TBD - what should code do if invalid data entered. Try again?
}
char *read_line(char *dest, sizeof size, const char *prompt) {
if (prompt) fputs(prompt, stdout);
fflush(stdout); // insure output is written before asking for input
char buffer[size * 2 + 1]; // form buffer at _least 1 larger for \n
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
return NULL;
}
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n') buffer[--len] = '\0';
if (len >= size) {
// input too big - how do you want to handle this?
TBD_Code();
}
return strcpy(dest, buffer);
}
Now use these 2 helper functions for clean user input
// printf("Do you want to log in(1) or register (2)? \n");
// scanf("%d",&number);
number = read_int("Do you want to log in(1) or register (2)? \n");
...
// printf("username : ");
// scanf("%s",&username);
read_line(username, sizeof username, "username : ");
// printf("Full name : ");
// scanf("%s",&fullName);
read_line(fullName, sizeof fullName, "fullName : ");
Additional code could be added to check for end-of-file, extremely long lines, int range testing, etc.
Use c library function fgets().
#include <stdio.h>
int main(){
Char username[10];
printf(“Username: “);
fgets(username,10,stdin);
}
I am trying to learn to program in C but am having trouble with manipulating strings as C treats strings as arrays.
My aim was to make a program that stores the users first name and surname.
Here is my progress:
#include <stdio.h>
int main(int argc, const char * argv[]) {
//defining the variables
char first_name[100];
char surname[100];
char ch[2];
// Asking for the first name and storing it
printf("What's your first name?\n");
scanf("%s", first_name);
// Prints the first name
printf("Hey %s!\n",first_name);
//Asks the user if they want to store their surname
printf("Would you like to tell me your second name? This is optional so type 'Y' for yes and 'N' for no.\n");
scanf("%s", ch);
//validate if they want to store it or not
if (ch == "Y"){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
return (0);
}
However, with this code, I get an error because my IDE(xCode) tells me to use the strcmp function. I then edited the code to become this:
if (strcmp(ch, "Y")){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
However variable ch is not a literal and so is not comparable.
Sidenote
I did try to compare two literals too, just to see how it works:
char *hello = "Hello";
char *Bye = "Bye";
if (strcmp(hello, Bye)){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
But even this gave an error:
Implicitly declaring library function 'strcmp' with type 'int (const *char, const *char)'
I believe I am not able to do this due to my lack of experience so it would be much appreciated if you could help me understand what I'm doing wrong and how I can fix the problem.
You need to include the appropriate header:
#include <string.h>
Also note that your desired logic probably calls for:
if (!strcmp(hello, Bye))
Instead of:
if (strcmp(hello, Bye))
Since strcmp returns 0 in case of equality.
There are several issues you should correct concerning how you handle input with scanf. First always, always validate the number of successful conversions you expect by checking the return for scanf. Next, as mentioned in the comment, there is NO need to include <string.h> in your code to make a one-letter comparison. Use a character comparison instead of a string comparison. Lastly, always limit your input to the number of characters available (plus the nul-terminating character.
Putting the bits together, you could do something like the following:
#include <stdio.h>
#define MAXN 100
int main (void) {
char first_name[MAXN] = "", surname[MAXN] = "";
int ch;
printf ("What's your first name?: ");
if (scanf ("%99[^\n]%*c", first_name) != 1) {
fprintf (stderr, "error: invalid input - first name.\n");
return 1;
}
printf ("Hey %s!\n", first_name);
printf("Enter surname name? optional (Y/N) ");
if (scanf("%c%*c", (char *)&ch) != 1) {
fprintf (stderr, "error: invalid input - Y/N\n");
return 1;
}
if (ch != 'y' && ch != 'Y') /* handle upper/lower case response */
return 1;
printf ("Enter your surname?: ");
if (scanf (" %99[^\n]%*c", surname) != 1) {
fprintf (stderr, "error: invalid input - surname\n");
return 1;
}
printf ("\nYour whole name is : %s %s\n", first_name, surname);
return 0;
}
Example Use/Output
$ ./bin/firstlast
What's your first name?: David
Hey David!
Enter surname name? optional (Y/N) Y
Enter your surname?: Rankin
Your whole name is : David Rankin
Look it over and let me know if you have any questions.
There are two problems here. Firstly you need to see what value is returned by the strcmp and secondly you must use the approprate hedder.
You must use:
#include <string.h>
Secondly, you must edit your if-else statement so it is like this:
if (strcmp(ch, "Y") == 0){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
We do this because the strcmp function returns a negative value if ch is smaller than "Y", or a positive value if it is greater than "Y" and 0 if both strings are equal.