This function writes to a txt file 3 user inputs; namely the ID, category and description. The ID should be an integer while the others should be strings.
#include <stdio.h>
#include <stdlib.h>
void addtask();
char menu();
int main() {
char selection ;
do {
selection = menu() ;
switch(selection) {
case '1': addtask(); break;
case '2': break;
default: printf("\n\n\nInvalid key entered");
}
}while(selection != '2');
return 0;
}
char menu() {
char option;
printf("\nWelcome to the task management system. Please enter a key to continue...\n");
printf("\n1) Add new task");
printf("\n2) Save and quit\n");
scanf("%c[^\n]", &option);
return option;
}
void addtask() {
int id;char category[21];char description[101];
printf("\nCreating new task...\n\n");
FILE * f = fopen("tasklist.txt", "r ");
if(f == NULL){
printf("File does not exist. Creating new file...");
f = fopen("tasklist.txt", "w");
}
else {
fseek(f, 0, SEEK_END); //move to end of cursor
printf("\nENTER id:");
scanf("%d", &id);
printf("\nEnter category (max 20 characters): ");
getchar();
fgets(category, 21, stdin);
printf("\nEnter description (max 100 characters): ");
getchar();
fgets(description, 101, stdin);
printf("writing: %d \t %s \t %s \t", id, category, description);
fprintf(f,"%d \t %s \t %s \t", id, category, description);
}
fclose(f);
}
When I run the program and input 2 sets of ID, category and description, I get in the txt file
1 Cat1
esc1
2 Cat2
esc2
where I think I should expect
1 Cat1 Desc1
2 Cat2 Desc2
What's wrong?
CodePudding user response:
Due to the mix of scanf
and fgets
, you get some weird behavior.
The main issue is the user's "enter" (\n
) press when writing input to the terminal. scanf
leaves it be in the stdin
's buffer, while fgets
includes it in the string it puts the input into.
Lets focus in your addtask
function, inside the else
brackets:
scanf("%d", &id);
takes only the number the user entered, so stdin cleaned off the number, but it still has a\n
character inside it. The nextgetchar()
call discards it, which leaves u with a clean buffer.fgets(category, 21, stdin);
takes the next input the user writes, including the\n
character. You probably want replace it with a\0
character to match your format. you can do it with a line like:category[strcspn(category, "\n")] = '\0';
as suggested here.- Now, the next
getchr()
call simply "swallows" the first letter of the input the user writes next, which explains your missing letters in the descriptions. - Finally,
fgets(description, 101, stdin);
takes the rest of the user input, including the newline (\n
) character(which you should probably let be in this case, since you asked for a new line after each description).
Note: To fully match your requested format, you also need to remove the last tab char (\t
) from the line: fprintf(f,"%d \t %s \t %s \t", id, category, description);
. Since the last description string (%s
) already has a new line in it, and you wouldn't want your next line to start with a tab.