I am messing around with the function below, I want to end input capture when user enters a DOT character. It seems that getche() is not doing what it is intentended to do:
void Encode(FILE *fp)
{
char chWord[100];
char *chP;
printf("Enter a word or a sentence, close it by a \".\"\r\n");
scanf("%s",chWord);
if (chWord != '.')
{
for (chP = chWord; *chP != '\0'; chP++) //to print each digit till end of string \0
{
printf("%d ",*chP+10);
fprintf(fp, "%d ",*chP+10);
}
}
}
UPDATE
It seems that I was not clear enough. What I am trying to do is when user enters a DOT it should act like pressing ENTER key so the program goes to next step. Some sort of simulating ENTER key.
if (chWord != '.')
should be
if (*chWord != '.')
you are comparing a char pointer to a char instead of a char to another char.
be aware that the way this code is written the input ".123" will skip the printing segment. not sure if this is desireable to you or not.
The scanf family of function accept a (negative)character set as a format specifier.
You can do scanf("%[abc]", chWord); to accept only strings composed of the letters abc.
And you can also specify which characters not to accept. So scanf ("%[^.]", chWord); will accept a string composed of anything but a dot.
Edit
I forgot to mention, that the dot will remain in the input stream buffer, so to read and ignore it during the scanf itself (rather than flush the buffer or do a getchar), just add it to the end of the format string. I.e.:
scanf ("%[^.].", chWord);
OK, backing out that whole Answer based on your update...
The answer is no, there is no way to do what you want to do with scanf, or anything in standard C for that matter. What you're trying to do is platform (and possibly compiler) specific.
If you want to treat the '.' as a enter key press you have to do the magic yourself. So, since you didn't mention if you were using any specific OS or compiler I'll give you the first example that comes to mind.
This works with Windows MS VS:
#include <Windows.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
char key = 0;
int counter = 0;
char chWord[100] = {0};
while(counter < 100) {
while(!_kbhit()) { //While no key has been hit
Sleep(1); //Sleep for 1 ms
}
key = _getch(); //Get the value of the key that was hit
if(key == '.') //if it was a .
break; //act as if it were an "enter" key and leave
else
chWord[counter] = key;
counter++;
}
chWord[99] = '\0';
printf("The string was %s\n", chWord);
return 0;
}
Related
I want and searching for a function or an alternative that could replace the non-standard getch() function of C language. I want help if any any function which can replace the getch() function from the code below or an appropriate alternative.
I am doing this since my college has asked me not to use the conio.h header file in my C programs.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int i=0, j=0, memAlloc=1;
char *p, *q, a;
p=(char *)calloc(1, sizeof(char));
while(1)
{
a=getch(); //getch() function
if(a!='\b'&&a!='\r')
{
p[i]=a;
++i;
printf("%c", a);
memAlloc++;
p=realloc(p, memAlloc*sizeof(char));
}
if(a=='\b'&&i>=1)
{
printf("\b \b");
--i;
}
if(a=='\r')
{
p[i]='\0';
break;
}
}
printf("\n");
for (i=0; p[i]!='\0'; i++)
printf("%c", p[i]);
//Storing a string of only alphabets into a new dynamic array
q=(char *)calloc(1, sizeof(char));
memAlloc=1;
for (i=0; p[i]!='\0'; i++)
{
if (isalpha(p[I])) //Checking for alphabet
if(isupper(p[i]))
{
q[j]=p[i]+32; //If uppercase alphabet convert it to lowercase
memAlloc++;
q=realloc(q, memAlloc*sizeof(char));
j++;
}
else
{
q[j]=p[i];
memAlloc++;
q=realloc(q, memAlloc*sizeof(char));
j++;
}
}
q[j]='\0'; //Adding a null character to the end of the string
free(p);
printf("\n");
for (i=0; q[i]!='\0'; i++)
printf("%c", q[i]);
}
Here is the explanation of the program.
The program will take a string input from the user of unknown size and save it to the dynamic array. The user will keep on entering characters in a single line until he presses the enter key after which the whole string is saved to a dynamic array. The program then removes every character except alphabets and converting uppercase alphabets to it's lowercase and then saves the updated string to an another dynamic array.
try this scanf(" %c",&a);
also you can use getchar() but note that both of these functions(scanf and getchar()) will leave a \n in buffer and so in your next enter to loop , they will take that as input ,which means you can use two getchar() , or add a space in scanf like above.
as I see your code , you only want one character and no white-spaces which means you use scanf like above and that white space will be ignored.
If you can live with that the function will wait until it finds a newline or other whitespace character in stdin - the user needs to input more characters such as the newline made by the press to Return/ Enter - (contrary to the getch() function which does not wait for further input) you can use scanf() or getchar() (both header stdio.h) to get a single character from stdin:
a = getchar();
or
scanf("%c",&a);
Note, that in the case of getchar(), a shall be of type int instead of type char to catch the potential EOF which is returned by an error.
If you´re looking for a standard library function which does not wait for another character in stdin (unless it hasn´t encountered EOF) like getch(), the simple answer is:
There is no one. There are platform-dependent solutions only, like getch() for Windows and DOS is, but not a general standard one for all environments.
You can also use system command to control the terminal in linux like this:
char getch() {
char c;
system("stty raw -echo");
c = getchar();
system("stty -raw echo");
return c;
}
This function does not require the user to press enter and takes input from the user without echoing.
It requires you to add stdlib.h library to your code
Note: This function is only applicable to UNIX-based OS
I was wondering how I can get scanf to skip reading a character if I press enter... My code is the following:
#include <stdio.h>
int main(void)
{
int a, status;
char b;
printf("Please enter a positive number immediately"
"followed by at most one lower-case letter:\n\n");
status = scanf("%i%c", &a, &b);
if (status == 1 && getchar() == '\n') {
printf("\nThank you!\n");
}
return 0;
}
When I enter just a number and nothing else, I need to press enter again to trigger the %c, &b in scanf. How do I avoid that and get the program to accept just 1 number to jump to the printf?
I tried:
if (status == 1 && getchar() == '\n')
but that won't work.
As noted in the comments, your best course of action is to use fgets to just read in a string, then parse and validate it. This Thread will provide you with enough resources for you to educate yourself about the use of fgets.
Here is one approach you can take. Please note that this code does not attempt to validate every possible input a user can provide, but rather give you a reasonable direction you can take to solve your problem if the input is assumed correct. I will leave the task of validation to you. The code below should provide enough tools to accomplish the rest of your task. Look at using a for loop to step through the buffer and ensure the input is correct. Use isalpha() and isdigit() to test each character. You can also implement your own functions to test each character as is done
in this answer.
#include <stdio.h>
#include <stdlib.h> //for atoi()
#include <string.h> //for strlen()
#include <ctype.h> //for isalpha()
#define MAX_INPUTLENGTH 500
int main(void)
{
//Always a good idea to initialize variables to avoid Undefined Behaviour!
char buffer[MAX_INPUTLENGTH] = { '\0' };
int a = 0, status = 1, length = 0;
char b = '\0';
printf("Please enter a positive number immediately"
"followed by at most one lower-case letter:\n\n");
//this gets you a string you can work with
fgets(buffer, sizeof(buffer), stdin);
length = strlen(buffer);
buffer[length - 1] = '\0';//remove the trailing '\n'
length--;
//now see if last character is a letter
if (isalpha(buffer[length - 1])) {
b = buffer[length - 1];//then assign and..
buffer[length - 1] = '\0';//trim the letter
}
//this function converts the remaining string to an int
a = atoi(buffer);
//Use the debugger and observe how these functions work in order
//to validate the input. for now, status is always 1!
if (status == 1) {
printf("\nThank you!\n");
}
return 0;
}
As noted in the comments below by #Jonathan, to portably get the count of an array, one should use sizeof(buffer) / sizeof(buffer[0]). Since you are using a char[], sizeof(buffer[0]) evaluates to 1, thus can be omitted when calling fgets.
I'm pretty new in C, I used to work in Python, and I'm trying to see if something that I read is integer number. If not, to read until I manage to entry a number.
I did some research and I found out that the function scanf actually returns 1 if the read is done suitably, and 0 otherwise.
So, I have written this code, and I don't understand why this is an infinite loop, writing "Give an integer" on the console
#include <stdio.h>
int main() {
int a;
int b = 1;
do {
printf("Give an integer\n");
b = scanf("%d", &a);
} while (b == 0);
}
The problem with scanf() is that it stops reading when the first white space is encountered for most specifiers like "%d", so it's left in the input and that's why reading again would cause a problem if you don't discard such white space because it will then return immediately the next time you call it. There is a mandatory white space that is introduced when you press Enter or Return, the '\n' new line character (or line feed).
If you want to read an integer and make sure you did you can try like this
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int
main(void)
{
long int value; // You can adapt this to use `int'
// but be careful with overflow
char line[100];
while (fgets(line, sizeof(line), stdin) != NULL) {
char *endptr;
value = strtol(line, &endptr, 10);
if ((isspace(*endptr) != 0) && (endptr != line))
break;
}
fprintf(stdout, "%ld\n", value);
return 0;
}
read strtol()'s manual to understand this code
You could as suggested in the comments, remove the white space characters from the input, but IMHO that is harder and you would still have other problems with scanf(), like handing empty input which is not straight forward.
I don t understand why this is an infinite loop, writing "Give an intiger" on the console
The problem is that scanf() does not consume data that it cannot match against the specified format. It leaves such characters unread in the input stream. Therefore, if you try reading again from the same stream with the same format, without consuming at least one character by some other means, then you can be certain that the input will again not be matched. And again. And again.
To avoid your infinite loop, you need to consume at least one character of the non-matching input after each matching failure. There are many ways you could do that; here's a fairly simple one:
#include <stdio.h>
int main() {
int a;
do {
printf("Give an intiger\n");
if (scanf("%d", &a)) {
// breaks from the loop on a successful match or an error
break;
}
// consume the remainder of one line of input without storing it
if (scanf("%*[^\n]") == EOF) {
break;
}
} while (1);
}
That consumes the whole remainder of the line on which the non-matching input is encountered, which will yield less surprising interactive behavior for some inputs than many alternatives would.
If you've a penchant for writing terse code, or if you don't like to break out of the middle of a loop, then you might write the same thing like this:
#include <stdio.h>
int main() {
int a;
do {
printf("Give an intiger\n");
} while ((scanf("%d", &a) == 0) && (scanf("%*[^\n]") != EOF));
}
Because the && operator short circuits, the second scanf() call will be executed only if the first returns zero, and the loop will exit after the first iteration wherein either the first scanf() call returns nonzero or the second returns EOF (indicating an error).
I Am trying to make a program to make the user to enter his first name then middle then last name each followed by space like this example:
sample input: mark brown ashraf
sample output: m b a
and when i debug i got "access violation error"
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main(void)
{
char name[100];
int i=0;
printf("Enter the name :");
gets(name);
while (name[i]!='\0')
{
if (name[i]==' ')
{
i++;
printf("%c",name[i+1]);
}
i++;
}
getch();
}
"now it dont give me the first initial but printed the rest of initials "
The access violation happens, because you use the wrong format specifier in your printf call.
printf("%s", name[i+1]);
should be
printf("%c", name[i+1]);
or maybe even more directly:
putchar(name[i+1]);
The violation occurs, because %s expects a pointer, which the printing function then dereferences. The char value you pass isn't a valid memory address.
Please switch on compiler warnings. They can usually tell you that your format string doesn't match the arguments.
Edit Besides the access violation, there are more problems in your program:
You increment i twice after a space, so that you actually print the second letter of each word. (Or even a space if your input is "Taylor C Huckleberry").
You don't catch the first word, unless your input begins with a space character.
You could end up printing the '\0' character when your input has trailing spaces.
You could print additional spaces if your input has subsequent spaces.
There are also some formal programming errors:
main is supposed to return an int, but your code never does.
You use the obsolete gets, which has been superseded with the more secure fgets. (Unformtunately, fgetskeeps a trailing newline, but it shouldn't matter for your code.)
In my opinion, a better approach is to keep track of the previously read character and to print the initial only if the previous char was a space and the current one is a letter. The header <ctype.h> provides the handy functions isspace and isalpha to check this. The previously read character starts off as a space character, so that you catch the first word:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char name[100];
char prev = ' '; /* pretend there's a space before the string */
int n = 0; /* number of initials printed */
int i = 0;
printf("Enter the name: ");
fgets(name, sizeof(name), stdin);
while (name[i]!='\0') {
if (isalpha(name[i]) && isspace(prev)) {
if (n++) putchar(' ');
putchar(name[i]);
}
prev = name[i];
i++;
}
putchar('\n');
return 0;
}
while (name[i]!='\0')
{
if (name[i]==' ')
{
i++;
printf("%s",name[i+1]);
}
i++;
}
SInce you are incrementing i twice inside the loop there is a possibility that you might have access array out of bound. This is a potential error.
gets() is no more a standard and you should use fgets() instead which will handle buffer overflow.
What's wrong in the below program (What's happening here)? It should break the for loop after the user inserts empty string (presses only ENTER), but in my case it ends in endless for loop. I tried what is in the comments with no success.
#include <stdio.h>
#include <string.h>
struct S {
char str [10];
};
int main(void)
{
int n;
struct S strings [10];
for (n = 0; n < 10; n++) {
# fflush(stdout);
scanf("%s", strings[n].str);
if (strlen(strings[n].str) == 0)
break;
# getchar();
}
printf("done");
return 0;
}
When I replace scanf with gets(strings[n].str); done is never printed. How would you fix it?
This sample solution works. Is there a difference in comparison to my code?
The enter key is not empty string, it is an ascii character or rather two characters a CR and LF (on Windows).
You shouldn't use strlen to find out if the input is empty. As others have said, when you press ENTER you get one or two characters sent to you.
You could instead check the first character in the string and see if it is '\n' or '\r'
scanf returns exactly what you've input... i.e. a crlf pair I'd imagine!
The problem with using scanf is that it expects something, not an empty string. You solve this by using e.g. fgets instead of scanf:
if (fgets(strings[n].str, sizeof(strings[n].str), stdin))
{
/* You got a string, it will contain the newline! */
}