Replacing spaces in string after input? - c

In the following code when the user enters a space at address the program falls into a infinite loop?
example: street,town, city would crash the program, how can I replace the spaces with a ','? or at least stop this from happening
printf("\nEnter address:\n");
scanf("%s", newNode->address);
printf("\nEnter department:\n");
scanf("%d", &newNode->depart);
while(validDate == 0){
printf("\nEnter Data Of Join(dd/mm/yy):\n");
if (scanf("%d%*[-/. ]%d%*[-/. ]%d", &newNode->day, &newNode->mounth, &newNode->year) != 3){
printf("Wrong format! Please enter a date and exclude the slashes! eg. 15 01 95");
}
else{
// break the loop
validDate = 1;
}
}// date validation end

try
gets()
instead of scanf(). The scanf will stop reading the input when it encounters a space character. And the remaining string data will stay in the input buffer and that may causing the issue.

Related

Scanf skips functions

I am working on my assignment and this is the issue that I bumped into. In the assignment, it says that the input value for the middle initals should be this - "L. A.". However, once I run my program it prints some printf functions on the same line, skipping the scanf function. I have went through a lot of topics about that " %c" issue, but I still can not make my program run properly. Some of the variables are from .h file. The actual assignment is bigger, however it is pretty much repetative so I thought if I figure out how to fix this certain issue I will be able to finally finish my assignment.
int main(void){
// Declare variables here:
char ch;
struct Name FullName = { {'\0'} };
struct Address AddressInfo = { 0, '\0', 0, '\0', '\0' };
struct Numbers PhoneInfo = { {'\0'} };
// Display the title
printf("Contact Management System\n");
printf("-------------------------\n");
// Contact Name Input:
printf("Please enter the contact’s first name: ");
scanf("%s", &FullName.firstName);
printf("Do you want to enter a middle initial(s)? (y or n): ");
scanf(" %c", &ch);
if (ch == 'y') {
printf("Please enter the contact’s middle initial(s): ");
scanf(" %s", FullName.middleInitial);
}
printf("Please enter the contact’s last name: ");
scanf(" %s", &FullName.lastName);
// Contact Address Input:
printf("Please enter the contact’s street number: ");
scanf("%d", &AddressInfo.streetNumber);
OUTPUT (I have highlighted input values):
Contact Management System
-------------------------
Please enter the contactÆs first name: *Artem*
Do you want to enter a middle initial(s)? (y or n): *y*
Please enter the contactÆs middle initial(s): *L. A.*
Please enter the contactÆs last name: Please enter the contactÆs street number:
The %s format specifier reads a sequence of characters terminated by whitespace. When you enter L. A., only L. gets read into middleInitial because it stops reading at the space and A. is left in the input buffer. On the next scanf, it immediately reads those buffered characters so it doesn't stop to prompt for anything.
The simplest way to handle this is to leave out the space when inputting, i.e. L.A.. If you want to support whitespace, you'll want to get rid of scanf entirely and read everything a full line at a time using fgets. Note that fgets also reads in the trailing newline, so you'll need to strip that out.

switch always default after I input data

Maybe there is no problem in running the first code
However,it will always default after I enter comment's data
char answer;
do{
printf("Do you want to add new comment?Y/N: ");
scanf("%c",&answer);
fflush(stdin);
switch(tolower(answer))
{
case 'y':
comment();
break;
case 'n':
main();
break;
default:
printf("Wrong choice !\n\n");
break;
}
}while(tolower(answer)!=='y'||'n');
there is the code of comment(),I guess the problem at here.
FILE*fp=fopen("comment.txt","a+");
if(fp == NULL)
{
printf("FIle not Found");
exit(1);
}
else
{
printf("Please enter your name: ");
gets(c.name);
printf("Pleas enter the date: ");
gets(c.date);
printf("Please enter the movie name: ");
gets(c.movie);
printf("Please enter your comment in 100 words:\n");
printf("Please press [Tab]and[Enter] to submit your comment\n");
scanf("%[^\t]",c.comment);
fprintf(fp,"%s %s\n%s\n%s\n\n",c.name,c.date,c.movie,c.comment);
}
fclose(fp);
Can someone help me?Thx!!
try using strlwr() instead of tolower()
Compiler gives you no error for while condition?
Maybe you want to write:
while(tolower(answer)!='y'||tolower(answer)!='n');
Inside do{}while you are reading input buffer which has a character you entered and a enter key. You need to clear that. Try scanf("%c%*c",&answer); .which will read that extra character from the buffer
A couple of problems in your code.
scanf("%c",&answer);
When you enter a character for the first time and if the character if either y or n then in next iteration this scanf() will read the stray \n (newline) character from the input buffer. To overcome this problem, add a space character before %, like this:
scanf(" %c",&answer);
Another problem is this statement:
while(tolower(answer)!=='y'||'n');
^^ ^
The compiler must be giving you both error and warning in this statement.
Change this to:
while(tolower(answer)=='y'||tolower(answer)=='n');
With this the loop to be run till user give input either y or n and for any other character, the loop will exit.
If you don't want loop to exit for any input character other then y or n but just print the message Wrong choice ! message then you can do:
}while(tolower(answer)!='y'||tolower(answer)!='n');

Fgets skipping input and printing next line?

I'm trying to read a string including spaces so scanf wouldn't work so I'm trying to use fgets. When I run it and it hits the if statement what prints on screen is:
Please enter the course name.
You entered the course:
Please enter the course ID.
=======================
if(coursetotal==0)/*start of 1 course*/
{
printf("Please enter the course name.\n");
fgets(course[0].name,sizeof(course[0].name),stdin);
printf("You entered the course name: %s\n",course[0].name);
printf("\nPlease enter the four digit course ID.\n");
int temp=0,temp1=0,count=0; /*Variables used to check if 4 digits*/
scanf("%d",&temp);
temp1=temp;
while(temp1!=0)
{
temp1/=10;
count++;
}
if(count==4)/*start of is 4 digits*/
{
course[0].id=temp;
coursetotal+=1;
printf("You entered the course ID: %d\n",course[0].id);
}/*end of is 4 digits*/
else
{
printf("The course ID you input was not 4 digits.\n");
return;
}
printf("You have successfully added the course: %s. The ID is : %d, and you now have a total of %d course.\n",course[0].name,course[0].id,coursetotal);
} /*end 1 course*/
First I have to address the pet peeve I see here:
I'm trying to read a string including spaces so scanf wouldn't work
That's not true at all. There's something called a negated scanset you can use it to read past the white space characters (such as space) that normally terminate scanf()s input for a string.
That said. You should really pick just one input mechanism scanf() or fgets() and use that exclusively. When you intermix, things get weird and missed. The fact that you've done it here tells me you've done it other places and you probably used scanf() prior to this leaving yourself an "unclean" stdin buffer. This will fix your issue.
Now just a quick example for you, given a int (num) and a char * (`string):
scanf("%d", &num);
fgets(string, sizeof(string), stdin);
printf("%d\n%s\n", num, string);
You'll seemingly skip the ability to enter anything for the fgets as it really just took int the newline character leftover from the scanf()'s number entry. You'll see on the output something like:
5
5
// <-- and a couple
// <-- of blank lines
Indicating that you picked up a newline character. Even more obvious if you were to look at the ASCII value of the string's first (and only) character:
printf("%d\n", string[0]); // this would yield 10 the ASCII value of \n

how to use fgets and sscanf for integers in loop

Beginner with C here. I am trying to run a loop where strings and ints are entered into various fields of a struct. When prompted for a 'last name', the user can press enter with no other input and the loop should end.
The problem is that with this code, the loop doesnt end (last name and first name entry requests run together on the same line) and the value for salary always comes out wrong (0 or some large number)
while (employee_num <= 2)
{
printf("Enter last name ");
fgets(employee[employee_num].last_name, sizeof(employee[employee_num].last_name), stdin);
if(strlen(employee[employee_num].last_name) == 0)
break;
printf("Enter first name ");
fgets(employee[employee_num].first_name, sizeof(employee[employee_num].first_name), stdin);
printf("Enter title ");
fgets(employee[employee_num].title, sizeof(employee[employee_num].title), stdin);
printf("Enter salary ");
fgets(strng_buffer, 1, stdin);
sscanf(strng_buffer, "%d", &employee[employee_num].salary);
++employee_num;
getchar();
}
If I try this code instead, I am able to exit the loop properly after the first run through it, but cannot exit after that (by pressing enter at the last name portion - perhaps a \n I cant seem to clear?):
char strng_buffer[16];
while (employee_num <= 5)
{
printf("Enter last name ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].last_name);
if(strlen(employee[employee_num].last_name) == 0)
break;
printf("Enter first name ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].first_name);
printf("Enter title ");
fgets(strng_buffer, sizeof(strng_buffer), stdin);
sscanf(strng_buffer, "%s", employee[employee_num].title);
printf("Enter salary ");
scanf("%d", &employee[employee_num].salary);
++employee_num;
getchar();
}
I am curious as to how to make this work as intended and what best practice would be for entries like this (ie use of sscanf, fgets, etc)
Thanks in advance!
The Loop breaks prematurely when it encounters the break statement
if(strlen(strng_buffer) == 0)
break;
The uninitialized character buffer strng_buffer, coincidently has null as the first character causing strlen to return 0
I believe you may have intended
if(strlen(employee[employee_num].last_name) == 0)
break;
as the loop terminatorm, and it was a typo in your part causing premature loop exit.
Assuming the fix mentioned by Abhijit, why transform the first into the second? Are you aware that the second behaves differently to the first, because of the addition of sscanf? If your intention was to shorten the first, the second seems quite bulky. Rather than adding sscanf to the situation, why not shorten the first by declaring a struct employee *e = employee + employee_num; and using that repetitively, instead of employee[employee_num]?
One "best practise" regarding fgets is to check it's return value. What do you suppose fgets might return, if it encounters EOF? What do you suppose fgets would return if it's successful?
One "best practise" regarding scanf is to check it's return value. In regards to the return value of scanf, I suggest reading this scanf manual carefully and answering the following questions:
int x = scanf("%d", &employee[employee_num].salary); What do you suppose x will be if I enter "fubar\n" as input?
Where do you suppose the 'f' from "fubar\n" will go?
If it's ungetc'd back onto stdin, what would your next employee's last name be?
int x = scanf("%d", &employee[employee_num].salary); What do you suppose x will be if I run this code on Windows and press CTRL+Z to send EOF to stdin?
int x = scanf("%d %d", &y, &z); What would you expect x to be, presuming scanf successfully puts values into the two variables y and z?
P.S. EOF can be sent through stdin in Windows by CTRL+Z, and in Linux and friends by CTRL+D, in addition to using pipes and redirection to redirect input from other programs and files.
The problem is that fgets returns the string with the line break (\n) included. So, even the user presses return without entering info, the string won't be empty. Also, your buffer size for salary is too small.
So, either you strip out the \n on every fgets or you change your check to:
if(strlen(employee[employee_num].last_name) == 1) break;
Also, when you're getting the buffer, change 1 to something bigger, like
fgets(strng_buffer, 10, stdin);
However, if you do want to strip out the \n from each fgets, you can do something like:
employee[employee_num].last_name[strlen(employee[employee_num].last_name)-1] = 0;
You can do this for every string or, better yet, create a function that does it.
EDIT: if you can guarantee that the user will press enter after each input then you can safely assume this. However if it's not always the case it's possible that the last character is not \n and just stripping this way might cause problems.

gets() only taking input once in while loop

I am new to C and working through some exercises, but having trouble with gets() in a while loop. In searching, I believe that it may have something to do with the \n character, but I was hoping that someone would be able to give me a more thorough explanation of what is going on here:
This loop will only run once - it will print the 'Enter last name' to screen a second time and then drop out of the loop before gets() has a chance to take any input a second time:
while (employee_num <= 10)
{
printf("Enter last name ");
gets(employee[employee_num].last_name);
if(strlen(employee[employee_num].last_name) == 0)
break;
printf("Enter first name ");
gets(employee[employee_num].first_name);
printf("Enter title ");
gets(employee[employee_num].title);
printf("Enter salary ");
scanf("%d", &employee[employee_num].salary);
++employee_num;
}
Thanks in advance!
You'd have a newline character (\n) in the input buffer after reading the salary. That is being picked up as the last name in the second iteration. You can ignore that by adding a getchar() after your last scanf:
while (employee_num <= 10) {
...
printf("Enter salary ");
scanf("%d", &employee[employee_num].salary);
++employee_num;
getchar();
}
Referring to answer by skjaidev,
With gets(), The newline character(\n), if found, is not copied into string and this is the reason for your problem.
Also,
Notice that gets is quite different from fgets: not only gets uses stdin as source, but it does not include the ending newline character in the resulting string and does not allow to specify a maximum size for str (which can lead to buffer overflows).
It is considered to be a bad practise to use gets() in a program

Resources