Read several ASCII characters and get the value - c

Can someone explain or correct me on the code i have?
I'm trying to input several characters and get the ascii value
ex: input: ab; output:9798
This is my code but there's a 10 at the end of it
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
printf("%d",c);
}
return 0;
}

If you look at ASCII table, a decimal value of 10 is a newline character. In other words, you process \n character as part of the input. This can happen when user copy-pastes multiple lines, or when Enter key is pressed, for example. If you do not want that to happen, you need to take extra care to ignore \n. For example:
#include <stdio.h>
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if (c == '\n')
break; /* Or perhaps continue? Depends on what you actually want. */
printf("%d",c);
}
return 0;
}
Also, note that different systems may have different conventions as for what newline actually is. On UNIX, it is \n character only, on Windows, it might be a combination or \r and \n. So if you want to make your program portable, this needs to be taken into account. You can either do it yourself, or use some other library (GNU getline comes to mind). You can read more about newline here.

You may want to exclude some chars from the output and not only '\n', in that case you can try something like this:
#include <stdio.h>
int isEndingChar(char c) {
char terminators[3] = {'\r','\t','\n'}
int n;
for( n=0; n<3; n++ ) {
if( terminators[i]==c )
return 1;
}
return 0;
}
int main() {
char c;
printf("Enter any character\n");
for (c=0; c<=122; c++)
{
scanf("%c", &c);
if( isEndingChar( c ) )
break;
printf("%d",c);
}
return 0;
}

Related

Why doesn't this get characters?

Why does this for only runs 5 times? As in it gets 5 character and then stops. And if I change the i<10 to i<5 it only runs 3 times.
#include <stdio.h>
char a[1000];
int main()
{
char a[100];
for(int i=0;i<10;i++)
{
scanf("%c",&a[i]);
}
}
I think the problem is most likely that you don't think the Enter key will give you a character, but it will result in a newline '\n' character.
If you want to skip the newlines (or really any white-space) then use a leading space in the scanf format string:
scanf(" %c",&a[i]);
// ^
// Note space here
If you want to read other space characters (like "normal" space or tab) then you need to use one of the character-reading functions like fgetc or getchar. For example as
for (size_t i = 0; i < 10; ++i)
{
int c = getchar();
if (c == '\n')
continue; // Skip newline
if (c == EOF)
break; // Error or "end of file"
// Use the character...
}

Scanf is skipped in while loop, causing infinite loop

The purpose of this code is so if the user enters an incorrectly formatted input, the program while ask the user to try again. For some reason though in my code, the scanf is constantly skipped after the first iteration, causing in infinite loop
#include <stdio.h>
int main() {
double A1;
int n1, loopchck, i=0;
while (i==0) {
printf("Enter a real number and inerger (A n): ");
fflush(stdin);
loopchck=scanf_s(" %lf %d", &A1, &n1);
if (loopchck == 2) {
i = 1;
}
else {
i = 0;
}
}
return 0;
}
For a start, lets think about what you want fflush(stdin); to do. fflush only operates on streams that have been written to; it causes any unwritten (cached) data to be fully written, and it makes no sense in the context of stdin.
This is a common mistake. When you tell scanf to read an integer (or a floating point, whatever) it'll stop reading when it no longer sees anything numeric. This means you'll probably have a leftover '\n' on the stream, at least. The user might have also entered other (erroneous) input that you want to discard.
The idea of discarding user input is horrible! You should think about accepting input in a different form (e.g. using argv in int main(int argc, char **argv)) to make their uncomfortable life a little more comfortable.
If you can't do that (or you don't want to), you can use one of the following pieces of code to discard up to (and including) the next '\n':
void fdiscardline(FILE *f) {
int c;
do {
c = fgetc(f);
} while (c != EOF && c != '\n');
}
void fdiscardline(FILE *f) {
fscanf(f, "%*[^\n]");
fgetc(f);
}
You should use this after your input, not before. Also, you need to think about what i should be. Should it be zero when more input can be read (e.g. while (i==0)), or zero when input wasn't read correctly? You need to be consistent because that's your loops terminal condition. For example:
#include <stdio.h>
int main() {
double A1;
int n1, loopchck, i=0;
while (i==0) {
printf("Enter a real number and inerger (A n): ");
loopchck=scanf_s(" %lf %d", &A1, &n1);
fdiscardline(stdin);
if (loopchck == 2) {
i = 0;
}
else {
i = 1;
}
}
return 0;
}

How to limit input length with scanf

In this program I have taken a dimensional character array of size[3][4],
as long as I enter a 3 characters for each row it will work well.
For example: if I enter abc abd abd I get the same output but if i enter more letters in the first or second or 3rd row I get an error.
How should I check for null character in 2 dimensional?
# include <stdio.h>
#include <conio.h>
# include <ctype.h>
void main()
{
int i=0;
char name[3][4];
printf("\n enter the names \n");
for(i=0;i<3;i++)
{
scanf( "%s",name[i]);
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
getch();
}
As pointed out by #SouravGhosh, you can limit your scanf with "%3s", but the problem is still there if you don't flush stdin on each iteration.
You can do this:
printf("\n enter the names \n");
for(i = 0; i < 3; i++) {
int c;
scanf("%3s", name[i]);
while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
}
How should I chk for null character in 2 dimensional ... [something has eaten the rest part, I guess]
You don't need to, at least not in current context.
The problem is in your approach of allocating memory and putting input into it. Your code has
char name[3][4];
if you enter more that three chars, you'll be overwriting the boundary of allocated memory [considering the space of \0]. You've to limit your scanf() using
scanf("%3s",name[i]);
Note:
change void main() to int main(). add a return 0 at the end.
always check the return value of scanf() to ensure proper input.
EDIT:
As for the logical part, you need to eat up the remainings of the input words to start scanning from the beginning of the next word.
Check the below code [Under Linux, so removed conio.h and getch()]
# include <stdio.h>
# include <ctype.h>
int main()
{
int i=0; char name[3][4];
int c = 0;
printf("\n enter the names \n");
for(i=0;i < 3;i++)
{
scanf( "%3s",name[i]);
while(1) // loop to eat up the rest of unwanted input
{ // upto a ' ' or `\n` or `EOF`, whichever is earlier
c = getchar();
if (c == ' ' || c == '\n' || c == EOF) break;
}
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
return 0;
}
(Cringing after reading the answers to date.)
First, state the problem clearly. You want to read a line from stdin, and extract three short whitespace separated strings. The stored strings are NUL terminated and at most three characters (excluding the NUL).
#include <stdio.h>
void main(int, char**) {
char name[3][4];
printf("\n enter the names \n");
{
// Read tbe line of input text.
char line[80];
if (0 == fgets(line, sizeof(line), stdin)) {
printf("Nothing read!\n");
return 1;
}
int n_line = strlen(line);
if ('\n' != line[n_line - 1]) {
printf("Input too long!\n");
return 2;
}
// Parse out the three values.
int v = sscanf(line, "%3s %3s %3s", name[0], name[1], name[2]);
if (3 != v) {
printf("Too few values!\n");
return 3;
}
}
// We now have the three values, with errors checked.
printf("you entered these names\n%s\n%s\n%s\n",
name[0], name[1], name[2]
);
return 0;
}
you might consider something on the order of scanf( "%3s%*s",name[i]);
which should, if I recall correctly, take the first three characters (up to a whitespace) into name, and then ignore anything else up to the next white space. This will cover your long entries and it does not care what the white space is.
This is not a perfect answer as it will probably eat the middle entry of A B C if single or double character entries are mode. strtok, will separate a line into useful bits and you can then take substrings of the bits into your name[] fields.
Perhaps figuring out the entire requirement before writing code would be the first step in the process.

How to invalidate an input in c

I'm writing a program in C that is suppose to ask the user for a number.
The number has to be greater than zero and cannot have letters before or after the number. (ie: 400 is valid but abc or 400abc or abc400 is not). I can make my program invalidate everything besides 400abc. How would I make it invalidate an input if it starts valid then turns invalid? (I'm about 2 months into an intro to c class so my knowledge is very limited.)
#include<stdio.h>
int check(void);
void clear_input(void);
main()
{
int num;
printf("Please enter a number: ");
num = check();
printf("In Main %d\n", num);
}
int check(void){
int c;
scanf("%d", &c);
while (c < 0){
clear_input();
printf("Invalid, please enter an integer: ");
scanf("%d", &c);
}
return c;
}
void clear_input(void){
char junk;
do{
scanf("%c", &junk);
}while (junk != '\n');
}
You can also check whether ascii value of each char scanned from user input should lie in range 48-57, It will only then be integer value.
strtol can be used to do it, but it takes some extra work.
After running this code:
char *endptr;
int n = strtol(num_text, &endptr, 10);
n will contain the number. But you still have to check that:
1. *endptr=='\0' - this means strtol didn't stop in the middle. In 400abc, endptr will point to abc. You may want to allow trailing whitespace (in this case, check that endptr points to an all-whitespace string.
2. num_text isn't empty. In this case, strtol will return 0, but an empty string isn't a valid number.
Read the input as a line, using fgets.
Check if all characters are numeric.
If not, it's invalid. If yes, use sscanf to get the line into an int.
Check if the int is in the range; you're done.
Scanf with %d will treat the "400abc" as 400, all the trailing characters would be ignored, so there is nothing to worry about.
If you definitely want to treat "400abc" as an invalid input, then maybe you shouldn't use %d in scanf, use %s instead?
One way is to read the whole line as a string and check by yourself if it contains any non-digits.
The other way is reading the integer and then looking into the input using fgetc() to see if the next character after the detected input is valid. Or you could even use the same scanf() for this:
char delim;
if(scanf("%d%c", &c, &delim) == 2 && !isspace(delim))
// the input is invalid
You can read the number in a character array and validate it by checking if all the characters lie in the ascii range 48 to 57 ( '0' to '9' ) .If so your no. is valid otherwise you can safely regard it as invalid input.Here the the demonstration :
#include<stdio.h>
#include<string.h>
int conv( char * word )
{
int ans=0;
int res=0;
for(int i=0;i<strlen(word);i++)
if(word[i]>='0' && word[i]<='9')
ans=(ans*10) + (word[i] - '0');
else
res=-999;
if(res==-999)
return res;
else
return ans;
}
int main()
{
char a[10];
gets(a);
int b=conv(a);
if(b==-999)
printf("Invalid Entry.\n");
else
printf("Success.No is %d.\n",b);
return 0;
}
You can adjust for negatives as well by checking the first character in the word array to be '-' and adjusting the sign accordingly.
This is C99, so compile with -std=c99
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
bool getNum(int *n) {
char c, s[10];
if (!scanf("%9s", s))
return false;
for (int i=0; c=s[i]; i++)
if (!isdigit(c))
return false;
*n = atoi(s);
return true;
}
int main() {
int n;
if (getNum(&n))
printf("you entered %d\n", n);
else
printf("you did not enter a number\n");
}
The following is your check function rewritten to fix your problem, so try this:
int check(void){
int n;
char c;
while (EOF==scanf("%d%c", &n,&c) || n < 0 || !isspace(c)){
clear_input();
printf("Invalid, please enter an integer: ");
}
return n;
}

How to read from input until newline is found using scanf()?

I was asked to do a work in C when I'm supposed to read from input until there's a space and then until the user presses enter.
If I do this:
scanf("%2000s %2000s", a, b);
It will follow the 1st rule but not the 2nd.
If I write:
I am smart
What I get is equivalent to:
a = "I";
b = "am";
But It should be:
a = "I";
b = "am smart";
I already tried:
scanf("%2000s %2000[^\n]\n", a, b);
and
scanf("%2000s %2000[^\0]\0", a, b);
In the 1st one, it waits for the user to press Ctrl+D (to send EOF) and that's not what I want.
In the 2nd one, it won't compile. According to the compiler:
warning: no closing ‘]’ for ‘%[’ format
Any good way to solve this?
scanf (and cousins) have one slightly strange characteristic: white space in (most placed in) the format string matches an arbitrary amount of white space in the input. As it happens, at least in the default "C" locale, a new-line is classified as white space.
This means the trailing '\n' is trying to match not only a new-line, but any succeeding white-space as well. It won't be considered matched until you signal the end of the input, or else enter some non-white space character.
One way to deal with that is something like this:
scanf("%2000s %2000[^\n]%c", a, b, &c);
if (c=='\n')
// we read the whole line
else
// the rest of the line was more than 2000 characters long. `c` contains a
// character from the input, and there's potentially more after that as well.
Depending on the situation, you might also want to check the return value from scanf, which tells you the number of conversions that were successful. In this case, you'd be looking for 3 to indicate that all the conversions were successful.
scanf("%2000s %2000[^\n]", a, b);
use getchar and a while that look like this
while(x = getchar())
{
if(x == '\n'||x == '\0')
do what you need when space or return is detected
else
mystring.append(x)
}
Sorry if I wrote a pseudo-code but I don't work with C language from a while.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int main(void)
{
int i = 0;
char *a = (char *) malloc(sizeof(char) * 1024);
while (1) {
scanf("%c", &a[i]);
if (a[i] == '\n') {
break;
}
else {
i++;
}
}
a[i] = '\0';
i = 0;
printf("\n");
while (a[i] != '\0') {
printf("%c", a[i]);
i++;
}
free(a);
getch();
return 0;
}
I am too late, but you can try this approach as well.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i=0, j=0, arr[100];
char temp;
while(scanf("%d%c", &arr[i], &temp)){
i++;
if(temp=='\n'){
break;
}
}
for(j=0; j<i; j++) {
printf("%d ", arr[j]);
}
return 0;
}
#include <stdio.h>
int main()
{
char a[5],b[10];
scanf("%2000s %2000[^\n]s",a,b);
printf("a=%s b=%s",a,b);
}
Just write s in place of \n :)
//increase char array size if u want take more no. of characters.
#include <stdio.h>
int main()
{
char s[10],s1[10];
scanf("\n");//imp for below statement to work
scanf("%[^\n]%c",s);//to take input till the you click enter
scanf("%s",s1);//to take input till a space
printf("%s",s);
printf("%s",s1);
return 0;
}

Resources