I'm trying to identify a way in which when data is input like such:
Name Integer
Name Integer
Name Integer
.
Each time the Name and Integer are entered, and a newline is detected, stuff is done with that name and integer, then again, and again, until the '.' is detected.
I've tried getchar() loops, and IF statements to detect '\n' for example, but none seem to work. Any ideas?
What about using scanf()?
scanf("%s %d\n", my_string, &my_int);
http://linux.die.net/man/3/scanf
scanf("%s%d\n", name, &intVar);
if((*name=='.') && (*(name+1)=='\0')){
return 0;
}
this should be suffice
How about:
#include <string.h>
#include <stdio.h>
int main()
{
char input[30];
gets(input);
while(strcmp(input, ".") != 0)
{
// do stuff
gets(input);
}
return 0;
}
Don't use scanf directly. It's surprisingly hard to use. It's better to read an entire line of input (for example, with fgets) and to then parse it (possibly with sscanf).
Related
Basically I want to create a program that would have potential questions that might be in my upcoming exam in Digital Systems.
#include <stdio.h>
#include <string.h>
int main() {
char input1[600];
printf("What is the set of available registers?");
scanf("%s", &input1);
if(strcmp(input1, "registers, memory, hard disc") == 0){
printf("Good job! You got it right");
}
else {
printf("Wrong answer!");
}
So whenever I type "registers, memory, hard disc" when I'm asked it returns 1 instead of 0. I cannot see the problem. I am kind of new to C so sorry if it is a silly question.
As already said in the comments, scanf() with "%s" stops conversion at the first whitespace character. To read a whole line of text, use fgets():
#include <stddef.h>
#include <stdio.h>
#include <string.h>
// ...
char foo[100];
if(!fgets(foo, sizeof(foo), stdin)) // don't use sizeof on pointers
; // handle error // for that purpose!
size_t length = strlen(foo);
if(length && foo[length - 1] == '\n') // fgets also reads the newline character
foo[--length] = '\0'; // at the end of the line, this removes it.
Swordfish has already given a good answer, and fgets is preferable to scanf. However, I want to show how you would use scanf in this case:
if(scanf("%599[^\n]", input1) != 1) {
// Handle error
}
So what is different?
scanf returns the number of successfully assignments, so if this returns 1, then input1 has been assigned. If not, an error has occured.
Changed s to [^\n] to read until newline
Inserted 599 (one less than 600) so ensure that we don't write outside the array.
Removed & from input1. In this case, it would probably work anyway, but it is undefined behavior, which should be avoided at all costs.
Try change your scanf line from:
scanf("%s", &input1);
to:
scanf("%[^\n]", input1);
It worked out for me.
I have two pieces of codes to test how the two console I/O functions, getchar() & scanf(), handle the EOF. But I still do not have a clear comprehension about the actual operations behind the outputs and their behaviors. Can someone explains that for me? Thanks a lot! (I am using Windows OS)
// 1st piece of Code
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
while ((ch=getchar()) != EOF)
{
putchar(toupper(ch));
}
return 0;
}
If I type
abc
or
abc(ctrl+z)
The program will have the same outputs:
ABC
// 2nd piece of Code
#include<stdio.h>
int main(void)
{
int x;
while(scanf("%d",&x) != EOF)
{
/*Ctrl + z + Enter*/
printf("x=%d\n",x);
}
return 0;
}
If I type
123
The program will output:
x=123
Otherwise, if I type
123(ctrl+z)
The program will have an infinite output:
x=123
x=123
x=123
x=123
...
getchar() returns the value of the character converted to unsigned char or EOF in case of error.
The error can be "end of file" or something else; usually (for getchar()) the programmer does not care about the error, just that an error happened.
scanf() returns the number of values matched and assigned (basically the number of % in the format string) or EOF in case of error. Note that the number can be less than the number of % in case, for example, of badly formatted input
Just like for getchar() the error can be "end of file" or something else. Particularly, reading less than the number of % is not an error.
So you may prefer to test for the correct number of assignments rather than testing for error in scanf()
#include <stdio.h>
int main(void) {
int x;
while (scanf("%d", &x) != 1) {
/*Ctrl + z + Enter*/
printf("x=%d\n", x);
}
return 0;
}
The problem is that on Windows the EOF is put into the input buffer like a normal character (with the encoded value 26).
When reading character by character (with e.g. getchar) this is handled by the Windows run-time library. But it doesn't work like that with scanf because when scanf parses the input it's like another character. And as a non-digit it's an invalid character for te "%d" format, leading to your scanf Call to return 0 instead of EOF (since it's not parsed by the format).
One way to solve it is to press the Ctrl-Z sequence on its own new line.
Another (and more reliable) way to solve it is to check that scanf returns the number of formats you have in the string. In your case you should compare against 1 (as you have one format specifier).
void main(void)
{
char character;
do {
scanf("%c", &character);
printf("%c", character);
} while (character != EOF);
}
I'm going to process the input character by character, and I am only allowed to use scanf(). However, the while loop does not stop. Since I may need to process the input with multiple-line strings, it is impossible to add one more condition: character != '\n'.
Can somebody help me with this problem? Thanks!
You have an incorrect expectation. When scanf() encounters the end of the input before either matching an input item or recognizing a matching failure, it returns EOF. Under no circumstance does it modify the value of the datum associated with an input item that has not been matched.
You are ignoring scanf's return value, which is generally a perilous thing to do, and instead testing whether scanf records EOF in the object associated with the input item, which, in your particular case, it must not ever do.
For a start it should be int main...
Also you need to check the return value from scanf - please read the manual page.
Taking this into account, the code should look like this
#include <stdlib.h>
#include <stdio.h>
int main()
{
char character;
while (scanf("%c", &character) == 1) {
if (character != '\n) {
printf("%c", character)
}
}
return EXIT_SUCCESS;
}
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;
}
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! */
}