I'm trying to write some characters in this "arq.txt" file and it works well at the beginning, but when I type zero to restart the program, the Do / While loop no longer recognizes zero I can't get out of it anymore. Please help me! Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *p;
char ch;
int c = 1, i, cont = 0;
while(c) {
printf("\n-------- DIGITANDO VALORES --------\n");
p = fopen("arq.txt", "w");
do {
printf("Type: ");
scanf("%c", &ch);
getchar();
putc(ch, p);
cont++;
} while(ch != '0');
fclose(p);
p = fopen("arq.txt", "r");
for(i = 0; i <= cont; i++) {
ch = fgetc(p);
printf("%c\n", ch);
}
fclose(p);
printf("If you wish to finish program, please type zero: ");
scanf("%d", &c);
}
}
scanf("%c", &ch); reads left-over newline from scanf("%d", &c);.
Try scanf("%c", &ch); getchar(); --> scanf(" %c", &ch);. Note space
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 months ago.
I wrote this table writing program in which I wanted to give program ability to continue depending upon char input value but after taking input, Even if input is y the loop still doesnt execute and program moves towards next line
#include <stdio.h>
#include <conio.h>
int main()
{
int T, N, P;
int K = 1;
char ch;
do
{
printf ("\nWhich Number's Table do you want?");
scanf ("%d", &T);
printf ("\nTable should be Uptil?");
scanf ("%d", &N);
do
{
P= T * K;
printf("\n %dx%d = %d", T, K, P);
K= K + 1;
} while(K <= N);
printf("\nDo you want to continue (Y/N)?");
scanf("%c ", &ch);
} while (ch == 'y');
getch();
}
you needgetchar() to skip Enter(\n)
#include <stdio.h>
int main() {
int T, N, P;
int K = 1;
char ch;
do {
printf("\nWhich Number's Table do you want?");
scanf("%d", &T);
getchar();//================here========
printf("\nTable should be Uptil?");
scanf("%d", &N);
getchar();//================here========
do {
P = T * K;
printf("\n %dx%d=%d", T, K, P);
K = K + 1;
} while (K <= N);
printf("\nDo you want to continue (Y/N)?");
scanf("%c", &ch);
getchar();//================here========
} while (ch == 'y');
}
Just changing scanf("%c ", &ch); to scanf(" %c", &ch); fixed my problem.
I guess the character doesnt get read properly just due to the intendation
difference.
I have an exercise that I need to create a program to input all information of students as a student report as the source code below. I have a problem that I can't get a full stream input. It stepped over grade input and jumped to another student to input the next student's ID. I have put getchar() to get \n but it does not help. My problem is in the case 1 of the switch, so you just need to care only about it, the other cases do not make any sense in my question.
#include <stdio.h>
#include <string.h>
#define MAX 1000
typedef struct
{
char id[10];
char name[50];
float grade;
char assess;
}student;
char assess(int a)
{
if(a<4.00)
return 'F';
if(4.00<=a<6.00)
return 'D';
if(6.00<=a<7.00)
return 'C';
if(7.00<=a<8.50)
return 'B';
if(8.50<=a<10.00)
return 'A';
}
int main()
{
int choice;
int i=0, num=0;
int a=0, j=0;
student std[MAX], temp;
char search[50];
do
{
printf("Student Report\n");
printf("1.Input data\n2.Append data\n3.Sort data and print\n4.Search by names5.Quit\n");
printf("Your choice is: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
do{
printf("How many students you want to add?\n");
scanf("%d", &num);
if(num<0 || num>50)
printf("Your number must be positive or smaller than or equal to 50!\n");
}while(num<0||num>50);
for(i=a; i<num; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
getchar();
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
getchar();
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
a=num;
}
case 2:
{
do
{
printf("How many students you want to append?[0; %d]\n", MAX-num);
scanf("%d", &num);
}while(num<0||num>50-a);
for(i=a; i<num+a; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, MAX, stdin);
getchar();
printf("Student's name No.%d:", i);
fgets(std[i].name, MAX, stdin);
getchar();
printf("Student's grade No.%d:", i);
do
{
scanf("%f", &std[i].grade);
if(std[i].grade<0||std[i].grade>10)
printf("Please re-input grade, it must be between 0 and 10\n");
}while(std[i].grade<0||std[i].grade>10);
std[i].assess=assess(std[i].grade);
}
a=num+a;
}
case 3:
{
for(i=0; i<a; i++)
for(j=0; j<a; j++)
{
if(std[i].grade<std[j].grade)
{
temp=std[i];
std[i]=std[j];
std[j]=temp;
}
}
printf("ID\tName\t\t\tGrade\t\tAssessment\n");
for(i=0; i<a; i++)
printf("%-10s%-50s%-10.2f%-10c\n", std[i].id, std[i].name, std[i].grade, std[i].assess);
}
case 4:
{
printf("Student's name who you want to search: ");
fgets(search, MAX, stdin);
getchar();
for(i=0; i<a; i++)
if(strcasecmp(search, std[i].name)==0)
printf("%-10s%-50s%-10.2f%-10c\n", std[i].id, std[i].name, std[i].grade, std[i].assess);
}
case 5:
break;
default:
{
printf("Please reinsert your choice again\n");
break;
}
}
}while(choice!=5);
return 0;
}
The issue stems from \n not being consumed by scanf at first. To overcome the case I have added while ((c = getchar()) != '\n' && c != EOF);.
To get rid of \n character after fgets's usages, I'd prefer to use strcspn.
case 1:
{
do{
printf("How many students you want to add?\n");
scanf("%d", &num);
int c;
while ((c = getchar()) != '\n' && c != EOF);
if(num<0 || num>50)
printf("Your number must be positive or smaller than or equal to 50!\n");
}while(num<0||num>50);
for(i=a; i<num; i++)
{
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
std[i].id[strcspn(std[i].id, "\n")] = 0;
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
std[i].name[strcspn(std[i].name, "\n")] = 0;
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
a=num;
break;
}
Moreover, asses function can be simplified as the following.
char assess(double a)
{
if(a < 4.00)
return 'F';
if(a < 6.00)
return 'D';
if(a < 7.00)
return 'C';
if(a < 8.50)
return 'B';
if(a < 10.00)
return 'A';
else
return -1; // the error indicator to be handled.
}
Further, after each case, you should put break statements. Glance at switch usage.
Based on the recommendation I found here - I am not able to flush stdin
We can use the below snippet to get rid of the junk in the buffer.
int c;
while ((c = getchar()) != '\n' && c != EOF);
Now the question is - where to put it in your program?
Well, I put it in the for loop and got the program to run and read all the three params - viz. ID, name, grade; for several entries of students.
Please check the below modified snippet from your program.
for(i=a; i<num; i++)
{
int c; // line 1 added
while ((c = getchar()) != '\n' && c != EOF); // line 2 added
printf("Student's id No.%d:", i);
fgets(std[i].id, 10, stdin);
printf("Student's name No.%d:", i);
fgets(std[i].name, 50, stdin);
printf("Student's grade No.%d:", i);
scanf("%f", &std[i].grade);
std[i].assess=assess(std[i].grade);
}
I am new to C programming so please do forgive my naivety. The following program when outputted fails to print the last character of the input string as the first character of the output string.
For example:
Enter no. of elements: 5
Enter string: hello
The reversed string is: lleh
Why is the o not printing?
#include <stdio.h>
int main() {
printf("Enter no. of elements: ");
int n;
scanf("%d", &n);
char string[10000];
printf("Enter string: ");
for (int i = 0; i < n; i++) {
scanf("%c", &string[i]);
}
printf("The reversed string is: ");
for (int i = (n - 1); i >= 0; i--) {
printf("%c", string[i]);
}
printf("\n");
return 0;
}
There is a side effect you take care of:
After scanf("%d", &n);, there is a pending newline in the input stream buffer.
When you later input n characters, scanf("%c", &string[i]) first reads the pending newline, then the n-1 first characters you type and the remainder of your input stays in the input buffer.
scanf() is a very clunky function. It is difficult to use properly.
Here is a way to fix your problem:
#include <stdio.h>
int main() {
char string[10000];
int i, n, c;
printf("Enter no. of elements: ");
if (scanf("%d", &n) != 1 || n < 0 || n > 10000)
return 1;
// read and discard pending input
while ((c = getchar()) != '\n' && c != EOF)
continue;
printf("Enter string: ");
for (i = 0; i < n; i++) {
if (scanf("%c", &string[i]) != 1)
break;
}
// the above loop could be replaced with a single call to fread:
// i = fread(string, 1, n, stdin);
printf("The reversed string is: ");
while (i-- > 0) {
printf("%c", string[i]);
}
printf("\n");
return 0;
}
Your scanf() should start with a space( more info about that ). Here is the code:
#include <stdio.h>
int main() {
printf("Enter no. of elements: ");
int n;
scanf(" %d", &n);
char string[10000];
printf("Enter string: ");
for (int i = 0; i < n; i++) {
scanf(" %c", &string[i]);
}
/* Just to be safer. */
string[n] = '\0';
printf("The reversed string is: ");
for (int i = (n-1); i >= 0; i--) {
printf("%c", string[i]);
}
printf("\n");
return 0;
}
Adding the space to the format string enables scanf to consume the
newline character from the input that happens everytime you press
return. Without the space, string[i] will receive the
char '\n'
So, merely one space is put before format specifier %c at line 11.
scanf(" %c", &string[i]);
When I try to run the scanf inside of the if function after entering either 'a' or 'b', it immediately runs and exits the program without getting input. Is there a way to fix it so the scanf works inside of the if and else if functions?
#include <stdio.h>
#include <string.h>
int top=-1;
int word;
char stack_string[100];
void push(char word);
char pop(void);
int main()
{
char input;
char str[100];
int i;
printf("press [a] for palindrome check, [b] for string reversal:");
scanf("%c", &input);
if (input == 'b'){
printf("Input a string: ");
scanf("%[^\n]s", str);
for(i=0;i<strlen(str);i++)
push(str[i]);
for(i=0;i<strlen(str);i++)
str[i]=pop();
printf("Reversed String is: %s\n",str);
}
else if(input == 'a'){
char str[100];
int count = 0;
printf("Input a string: ");
scanf("%[^\n]s", str);
for (i = 0; i < strlen(str); i++)
{
push(str[i]);
}
for (i = 0; i < strlen(str); i++)
{
if (str[i]==pop())
count++;
}
if (count == strlen(str))
printf("%s is a palindrome\n", str);
else
printf("%s is not a palindrome\n", str);
}
return 0;
}
void push(char word)
{
top=top+1;
stack_string[top]=word;
}
char pop()
{
word = stack_string[top];
top=top-1;
return word;
}
Use this:
scanf(" %[^\n]s", str);
^^^
Whitespace
instead of
scanf("%[^\n]s", str);
For more information, refer this link.
Stop using scanf(). The terminal sends your application a full line at a time, but scanf() only consumes the parts it needs, i.e. one character in the case of %c or just all the digits in case of %d. The rest is left in the input buffer, where the following scanf() get them. That causes the user's input and what the program receives to be somewhat "out of sync".
It's better to read full lines at a time, with fgets() or getline(), and then parse whatever you want from them. E.g.:
#define LINELEN 255
char line[LINELEN];
fgets(line, LINELEN, stdin);
int num;
int a = sscanf(line, "%d", &num);
Use whatever format string you require on the sscanf() and put the whole thing in a function if you like. (LINELEN there is of course an arbitrary
limit, but fgets() requires some limit.)
See also: http://c-faq.com/stdio/scanfprobs.html and the longer explanation linked there.
use scanf like this: scanf("%s", str)
Only scanf statements need to be changed:
#include <stdio.h>
#include <string.h>
int top=-1;
int word;
char stack_string[100];
void push(char word);
char pop(void);
int main()
{
char input;
char str[100];
int i;
printf("press [a] for palindrome check, [b] for string reversal:");
scanf("%c", &input);
if (input == 'b'){
printf("Input a string:\n");
scanf("%s", str);
for(i=0;i<strlen(str);i++)
push(str[i]);
for(i=0;i<strlen(str);i++)
str[i]=pop();
printf("Reversed String is: %s\n",str);
}
else if(input == 'a'){
char str[100];
int count = 0;
printf("Input a string:\n");
scanf("%s", str);
for (i = 0; i < strlen(str); i++)
{
push(str[i]);
}
for (i = 0; i < strlen(str); i++)
{
if (str[i]==pop())
count++;
}
if (count == strlen(str))
printf("%s is a palindrome\n", str);
else
printf("%s is not a palindrome\n", str);
}
return 0;
}
void push(char word)
{
top=top+1;
stack_string[top]=word;
}
char pop()
{
word = stack_string[top];
top=top-1;
return word;
}
Can anybody help me with my code
int main(void){
int ctr,wordLength;
char theWord[99];
ctr = 0;
printf("Enter a Word: ");
scanf("%s", & );
printf("Enter the letter you want to find: ");
scanf("%s", & );
while(ctr < wordLength | theWord[ctr]=='a'){
ctr++;
}
//output
}
expecting output
Enter a Word: hello
Enter the letter you want to find: z
the letter z is not found in the word.
You can do it this way also,
#include <stdio.h>
int main(void)
{
int ctr;
char theWord[99], ch;
ctr = 0;
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf(" %c", &ch );
for(int i = 0; theWord[i]; i++)
{
if(theWord[i] == ch)
ctr++;
}
if(ctr != 0)
printf("word is found\n");
else
printf("word is not found\n");
}
Yes, we can do it it using while loop also,
int i = 0;
while(theWord[i] != '\0' )
{
if(theWord[i] == ch)
ctr++;
i++;
}
if(ctr != 0)
printf("word is found\n");
else
printf("word is not found\n");
Corrected code
int main (void)
{
int ctr = 0;
int wordLength;
char theWord[99], ch;
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf("%c", &ch);
while (theWord [ctr] != '\0')
{
if (theWord [ctr] == ch)
{
print("Character found at position %1", ctr);
break;
}
ctr++;
}
if (theWord [ctr] == '\0')
{
printf ("Character not found");
}
}
I did correction of your code, It works successfully with GCC
#include<stdio.h>
#include <string.h>
int main(void){
int ctr = 0,c = 0, wordLength;
char ch, theWord[99];
printf("Enter a Word: ");
scanf("%s", theWord);
printf("Enter the letter you want to find: ");
scanf("%c", & ch);
wordLength = strlen(theWord);
while(theWord[ctr] != '\0')
{
if (theWord[ctr] == ch)
{
printf("the letter %c is found in the word\n", ch);
c++;
}
ctr++;
}
if (c == 0 )
{
printf("the letter %c is NOT found in the word\n", ch);
}
}