Unable to understand - reading characters from files in C - c

I have just started learning file handling in C, and wondered if I could perform mathematical calculations by reading input from a file, here is the code for just reading the characters and displaying on the console :
int main(void)
{
FILE *p;
char a, b, c, ch;
p = fopen("numbers.txt", "a+");
while((ch = getc(p)) != EOF)
{
fscanf(p, "%c %c %c\n", &a, &b, &c);
printf("%c %c %c\n", a, b, c);
}
fclose(p);
return 0;
}
numbers.txt contains (with a space before each character) :
2 + 3
5 + 6
6 + 7
output obtained is :
2 + 3
+ 6
+ 7
I am unable to understand why first line output is as expected but second and third line have missing character, even though new line is given after each expression in numbers.txt.

An additional character is being scanned at the beginning of each iteration of your while loop
while((ch = getc(p)) != EOF)
Try making the fscanf() statement as the condition for your while loop and check for its return value. According to cplusplus.com:
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
So try changing your while condition to anyone of the following:
while (fscanf(p, " %c %c %c", &a, &b, &c) != EOF)
or
while (fscanf(p, " %c %c %c", &a, &b, &c) == 3)

Using whitespace in the scanf format specifier, like you do with \n, matches any amount of whitespace. The \n and the leading space on the next line are consumed, causing getc to remove the first digit instead of the leading space.
I’d skip getc entirely, as #BLUEPIXY suggested:
while (fscanf(p, " %c %c %c", &a, &b, &c) == 3) {
printf("%c %c %c\n", a, b, c);
}

Related

loop 2 taking input automatically

My code is behaving weirdly. In loop 1 it is working perfectly but in loop 2 it is automatically printing ASCII value 10. please help!.
#include<stdio.h>
int main(){
char c;
int loop =1;
do{
printf("\nLoop = %d\nWrite character of which you want to find acii values: ", loop);
scanf("%c", &c);
printf("\nASCII value of %c is %d.", c, c);
loop++;
}while(c != 'Z');
printf("\n******END*****");
return 0;
}
10 is ASCII for newline. You are reading whitespace, which you can avoid by using
scanf(" %c", &c);
Note the additional blank before the character specifier. It instructs scanf to ignore white space.

How to exit a scanf loop with newline character. Currently loops indefinitely

I am trying to get: while(scanf("%c %c %d\n", &a, &b, &c) && (a!='\n')) to exit once a line is blank, eg the following:
a b 12
q w 4
g u 80
(exit)
Code:
while(scanf("%c %c %d\n", &a, &b, &c) && (a != '\n'))
To read a line, use fgets(). Then, if successful, parse the input string for '\n', expected a,b,c, or anything else.
// c ' ' c ' ' d \n \0
#define LINE_EXPECTED_SIZE (1 + 1 + 1 + 1 + 11 + 1 + 1)
char buf[LINE_EXPECTED_SIZE * 2]; // let us be generous with size.
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
char a,b;
int c;
if (sscanf(buf, "%c %c %d", &a, &b, &c) != 3) {
// Note unexpected input
fprintf(stderr, "Unexpected bad input '%s'\n", buf);
break;
}
printf("a:'%c', b:'%c', c%d\n", a,b,c);
}
"\n" is rarely correct at the end of a scan() format. #Jonathan Leffler.
The above uses sscanf(...) != 3 to detect if 3 specifiers were matched. This will not detect if extra text was on the line. An advanced approach uses " %n" to scan optional following white-space and then note the scan offset at that point.
// if (sscanf(buf, "%c %c %d", &a, &b, &c) != 3) {
int n = 0;
sscanf(buf, "%c %c %d %n", &a, &b, &c, &n);
if (n == 0 || buf[n] != '\0') {
// if scanning did not reach %n or extra text followed ...

How to use fscanf, care about endofline?

I want to read int from a file
The first line is composed of 1 int and the second of 2
ie
1
2 3
if i do
fscanf(FILE, "%d \n %d %d", &a, &b, &c);
I obtain correctly the 3 numbers
but if i put all the numbers on the same line in the file
ie 1 2 3
I obtain the same result (and that's not what i want)
I want to know : How to force the user to go to a new line in his file ?
Edit :
As it seems unclear to some (i'm sorry for that) i want that the file
1
2 3
Produce the result :
a = 1
b = 2
c = 3
And the file
1 2 3
produce either an error or
a = 1
b = 0
c = 0
You need to read each line into a char buffer using fgets and parse each line with its own sscanf. You can use an extra %s on the end of the format string (and an extra pointer argument to a dummy variable of type char *) to detect whether the line contains extra stuff after the fields you're looking for.
fscanf(FILE, "%d", ...); first scans and discard white space before scanning for int characters. In scanning white-space, both ' ' and '\n' are treated the same, so using '%d' loses the end-of-line.
fscanf(FILE, "\n", ...); and fscanf(FILE, " ", ...); do the same thing: scan and discard any white space. Using "\n" does not scan only for '\n'.
Code could use fscanf(FILE, "%d%*1[\n]%d %d", &a, &b, &c) == 3, to find a '\n' after a, but additional '\n' could be lurking in other places.
The only way using scanf() family to detect a '\n' involves using '%c' or '%[]' or '%n'. It is easier to use fgets() and then parse with sscanf() or strtol().
int Read1and2int(FILE *stream, int *a, int *b, int *c) {
char buf[100];
int n;
if (fgets(buf, sizeof buf, stream) == NULL) return EOF;
int count = sscanf(buf,"%d %n", a, &n);
// Non-numeric or extra data
if (count != 1 || buf[n]) return 0;
if (fgets(buf, sizeof buf, stream) == NULL) return 1;
count = sscanf(buf,"%d%d %n", b, c, &n);
// Non-numeric or extra data
if (count != 2 || buf[n]) return 1;
return 3;
}

Work With Char Using If else in C Language

Whenever I use if Statement to make a decision by comparing a character using char and %d, then it results in false always.
example:
#include<stdio.h>
#include<conio.h>
int main(void) {
int a, b;
float r;
char op;
printf("Enter 1st num : ");
scanf("%d", & a);
printf("Enter 2nd Num : ");
scanf("%d", & b);
printf("Enter Operator ( +, - , * , /) : ");
scanf("%c", & op);
if (op == '+') {
r = a + b;
printf("Ans = %f", r);
getche();
} else if (op == '-') {
r = a - b;
printf("Ans= %f", r);
}
//same as above for remaining 2 functions of * and /
else
printf("Error Occurred");
}
After typing the second number you press enter, right? %c in scanf accepts the first character it finds, so it returns the line break character corresponding to you pressing enter.
An easy fix is to add a space character before %c. It makes scanf skip any whitespace.
scanf(" %c",&op);
From the scanf documentation (http://www.cplusplus.com/reference/cstdio/scanf/):
Whitespace character:
The function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters -- see isspace). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).
Because %d ignore white-spaces and special characters. White-spaces and special characters are chars. So, %c has to take white-spaces and special characters as inputs.
You can test the output of the code below.
#include <stdio.h>
int main(void)
{
char p = 'w';
char l = 'x';
char t = 't';
printf("Give one, two or three chars: ");
scanf("%c%c%c", &p, &l, &t);
printf("p = %c, l = %c, t = %c \n", p, l, t); //
scanf("%c", &t);
printf("plt = %c%c%c \n", p,l,t);
return 0;
}

"printf" and "scanf", something wrong with stream

So here is my code.
int main(int argc, char* argv[])
{
char c;
size_t place;
while (1) {
scanf("%c %u", &c, &place);
printf("%c\n", c);
}
return 0;
}
When I compiled and ran program I expected to see terminal like this:
a 1
a
b 2
b
c 3
c
But I saw this:(some extra '\n')
a 1
a
b 2
b
c 3
c
Please help me find what I did wrong.
You may try like this:
scanf(" %c %u", &c, &place);
^^--Add space here
instead of
scanf("%c %u", &c, &place);
printf("char is %c\n", c); Adding some string before printing the received character will helps you to understand more clearly why its behaving like this. After your input some blank spaces or new line is entered, that is used in the next scanf. You can even print the ascii value of the charater like printf("char is %d, %c", c, c); and serach the ASCII value in the ASCII table, to understand exactly which value (blanks or new line or tab) scanf has received mistakenly.
Keeping blankspace as first character in format string of scanf will helps to skip all leading blanks(including tabs and newline). Like scanf(" %c %u", &c, &place);

Resources