What is going wrong when using getchar for my C program? - c

Hello folks it's my first question here :)
I just started studying CS in Berlin and tried to write a prog on my own which prints every charakter of a string literally in the terminal. And it works fine when defining the word which has to be printed in the C-Code.
int main () {
printf("Type in a word:\n");
char wort[] = "raffiniert";
int i = 0;
if (wort[i] == i)
{
printf("No word typed in!\n");
return 0;
}
while (wort[i] != '\0')
{
printf("%c \n", wort[i]);
i++;
}
return 0;
}
But when trying to implement getchar, so u can type in the console, not in the code, it fails. Regardless of how much other things I tried.
#include "stdio.h"
#include "stdlib.h"
int main ()
{
printf("Type in a word:\n");
int i = 0;
char wort;
wort = getchar();
if ((wort = getchar()) == i)
{
printf("No word typed in!\n");
return 0;
}
while ((wort = getchar()) != '\0')
{
printf("%c \n", wort);
}
return 0;
}
My problems are:
The program does not terminate automatically after printing out.
The first time typing in a word, it's printed uncompletely. It starts to print completely after the first time.
Could y'all at least give me advices what to correct?
Thanks and stay in good health.

"The program does not terminate automatically after printing out."
That's because your loop condition is incorrect. You want to check if getchar() returns EOF.
"The first time typing in a word, it's printed uncompletely. It starts to print completely after the first time."
That is because you are discarding the first two characters of input. You have 2 calls to getchar() where you basically discard the result. Just do:
#include <stdio.h>
int main (void)
{
int wort; /* Must be int to compare with EOF */
int i = 0;
while( (wort = getchar()) != EOF ){
putchar(wort);
i += 1;
}
if( i == 0 ){
fprintf(stderr, "No word typed in!\n");
return 1;
}
return 0;
}

Related

C - Getting segmentation fault with the fgets() in a loop

I'm new at C and I'm having some issues with my code. I'm trying to do a loop to read every input from a user, until he press ENTER and get out of the loop to execute other functions. Here's my code:
int main(char argc,char *argv[]){
char input[200];
char *epc;
int err = 0;
int idt = 0;
while (fgets(input,200,stdin) != NULL){
epc = strchr(input, ' ');
idt = epc[2] - '0';
if(idt == 1){
err++;
}
}
}
printf("Success");
return 0;
}
So basically if someone enters 5 01, it should go through the loop, and then if the user
enters again nothing by pressing the ENTER key, it should break out of the loop and print Success.
Except it doesn't work and I'm getting a segmentation fault in the terminal every time.
If I do it with an artificial loop, example while(i<3) and i++ at the end of the loop to break, it does work.
Can you help me out please?
The flaw is that you expect fgets to return NULL if the user presses just ENTER, but that's not what happens. In that case, fgets returns just the newline, so input is the string "\n". Then strchr tries to find a space in the string "\n" but there is none, so it returns NULL and then espace[2] dereferences NULL causing the segfault.
If you want the loop to break upon user pressing just ENTER, then you'll need to test for getting the string "\n". You could do something like
while (fgets(input,100,stdin) != NULL){
if(input[0] == '\n'){
break;
}
Also note that there are other inputs that would cause problem. Anything where the first space has less than 2 characters following it, (such as "0 1") will cause espace[2] to index to the string terminator or beyond.
you are facing segmentation when you just press enter instead of giving some input, in that case your strchr returns NULL to espace and you are trying to extract something out of it by using identification = espace[2] - '0';
use below way to guard against the NULL handling.
#include <stdio.h>
#include <string.h>
int main(char argc,char *argv[])
{
char input[200];
char *epc;
int err = 0;
int idt = 0;
printf("Enter some words\n");
while (fgets(input,100,stdin) != NULL){
printf("input is : %s\n", input);
epc = strchr(input, ' ');
if(epc)
{
idt = epc[2] - '0';
if(idt == 1){
err++;
}
}
}
printf("Success");
return 0;
}

C program reads one char at a time, but never reaches EOF?

I'm writing a program that needs to read input one character at a time and transform that input, and I need to be able to differentiate the end of a line (\n) and the end of the stdin. For whatever reason my program just loops infinitely after it gets to the last line and never prints it. I'm wondering why it's never catching EOF? I took out some of the code from the bottom because it's just a ton of if statements replacing characters with uppercase characters and such. I basically just don't understand why my code is never breaking.
#include <stdio.h>
#include <string.h>
int main(void)
{
int MAXCHARS = 79;
int curr;
char currline[MAXCHARS*2];
char lastline[MAXCHARS*2];
memset(currline,0,158);
memset(lastline,0,158);
int pointer = 0;
while (1)
{
curr = getchar();
if (curr == EOF)
{
for (int i = 0; i < pointer; i++)
{
printf("%c", currline[i]);
}
break;
}
if (curr == '\n')
{
if (currline == lastline)
{
pointer = 0;
}
else
{
strcpy(lastline,currline);
for (int i = 0; i < pointer; i++)
{
printf("%c", currline[i]);
}
pointer = 0;
}
}
}
}
As far as I can understand, your program never reaches that block of code, because it never gets EOF. Try Ctrl+Z for Windows or Ctrl+D for Linux.
Also see https://en.wikipedia.org/wiki/End-of-file and What is considered as EOF in stdin?

print each letter after '.' for example if I enter a..bcde..fg..h the program will print bfh

I'm new to C, I have been asked to make a program in C asking to print each letter after a '.' after a user has entered an input.
For example if the user enters a..bcd..e.f..gh the output should be befg
which is the exact example I have been given in class.
I assume this would need to use pointers but I am unsure how to deal with this question, here is what I have tried to do so far. I know it is not correct, please help me understand how to use pointers to deal with this question.
#include <stdio.h>
int main() {
char *c, count =0;
printf("enter some characters");
scanf("%s", &c);
while( c != EOF ) {
if (c != '.') {
count ++;
}
else; {
printf("%s", c);
}
}
}
The program can look the following way
#include <stdio.h>
#define N 100
int main( void )
{
char s[N];
const char DOT = '.';
printf( "Enter some characters: " );
fgets( s, N, stdin );
for ( char *p = s; *p; ++p )
{
if ( p[0] == DOT && p[1] != DOT ) putchar( p[1] );
}
putchar( '\n' );
}
Its output might look like
Enter some characters: a..bcd..e.f..gh
befg
Take into account that here any symbol after a dot (except the dot itself) is printed. You can add a check that there is a letter after a dot.
You don't really need pointers for this, or even an array. Basically it's a simple state engine: read each character, if '.' is encountered, set a flag so the next character is printed.
#include <stdio.h>
int main() {
int c, flag = 0;
while ((c = getchar()) != EOF) {
if (c == '.')
flag = 1;
else if (flag) {
putchar(c);
flag = 0;
}
}
return 0;
}
There are some errors in your code:
- char* c means a pointer to one or more characters.
But where does it point to?
- scanf reads a string up to an "white space". White space characters are the space itself, a newline, a tab character or an EOF. scanf expects a format string and a pointer to a place in memory where it places what it reads. In your case c points to an undefined place and will overwrite whatever there is in memory.
- why do you place a ";" after the else? The else clause will end with the ";". So your program will do the print every time.
It helps you a lot if you format your code in a more readable way and give the variable names that give hint what they are used for.
Another very important thing is to initialize every variable that you declare. Errors with uninitialized variables are sometimes very hard to find.
I would do it this way:
#include <stdio.h>
int main(int argc, char* argv[])
{
// I read every single character. The getchar function returns an int!
int c = 0;
// This marks the program state whether we must print the next character or not
bool printNext = false;
printf("enter some characters");
// We read characters until the buffer is empty (EOF is an integer -1)
do
{
// Read a single character
c = getchar();
if ( c == '.')
{
// After a point we change our state flag, so we know we have to print the next character
printNext = true;
}
else if( c != EOF )
{
// When the character is neither a point nor the EOF we check the state
if( printNext )
{
// print the character
printf( "%c", c );
// reset the state flag
printNext = false;
}
}
// read until the EOF occurs.
}
while( c != EOF );
}
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char letter;
char *c;
c = malloc(256);
printf("enter the string : ");
scanf("%s", c);
while( (letter=*(c)) != '\0' )
{
if (letter == '.')
{
c++;
letter=*c;
if(letter!='.')
printf("%c",letter);
else
{
while(letter=='.')
{
c++;
letter=*c;
}
printf("%c",letter);
}
}
c++;
}
printf("\n");
}

Get text while not EOF

Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 256
int main(int argc, const char * argv[]) {
char testo[N];
int i;
printf("PER TERMINARE L'INSERIMENTO PREMERE CTRL+Z oppure CTRL+D \n");
for(i=0;i<N;i++)
{
scanf("%c",&testo[i]);
/* if(testo[i]=='h' && testo[i-1]=='c')
{
i--;
testo[i]='k';
}
if(testo[i]==testo[i-1])
{
i--;
} */
if(testo[i]==EOF)
{
break;
}
}
puts(testo);
return 0;
}
When the code in /* ... */ is compiled, I can't stop the insert of text with EOF, but when the code is built and run as shown here, the EOF works.
Does anyone have any idea what the problem is?
You're testing for EOF incorrectly. With scanf(), you need to look at the return value. In fact, with almost all input functions, you need to test, if not capture and test, the return value.
Superficially, you need:
for (i = 0; i < N; i++)
{
if (scanf("%c", &testo[i]) == EOF)
break;
…
}
However, in general, you should check that scanf() made as many successful conversions as you requested, so it is better to write:
for (i = 0; i < N; i++)
{
if (scanf("%c", &testo[i]) != 1)
break;
…
}
In this example, it really won't matter. If you were reading numeric data, though, it would matter. The user might type Z instead of a number, and scanf() would return 0, not EOF.
To detect EOF, check the result of scanf()
if scanf("%c",&testo[i]) == EOF) break;
Note: testo[] may not be null character terminated. To print as a string, insure it is.
char testo[N];
int i;
// for(i=0;i<N;i++) {
for(i=0;i<(N-1);i++) {
if (scanf("%c",&testo[i]) == EOF) break;
}
testo[i] = '\0'; // add
puts(testo);
To stop at end of file, check the return value from scanf:
scanf returns the number of inputs correctly parsed. In your case, %c reads a byte from the stream correctly as long as end of file has not been reached. if (scanf("%c",&testo[i]) != 1) break; will do.
Yet using scanf to read one byte at a time from the input stream is overkill. The idiomatic way to do this in C is using the getchar() or the getc() function. The return value must be stored in an int variable and has special value EOF upon end of file.
You should also make the array 1 byte longer and store a null byte at the end to make it a C string, as expected by puts.
Here is a modified version of your program:
int main(int argc, const char *argv[]) {
char testo[N+1];
int i;
printf("PER TERMINARE L'INSERIMENTO PREMERE CTRL+Z oppure CTRL+D\n");
for (i = 0; i < N; i++) {
int c = getchar();
if (c == EOF)
break;
testo[i] = c;
/* ... further processing ... */
}
testo[i] = '\0';
puts(testo);
return 0;
}

scanf() in a loop

I am trying to make a program where the computer has to guess a number between 0 and 100 picked by the user(me). The program should guess the number within 7 tries which it does, but I'm having a problem with scanf(). When the program tries to guess the number, the user must tell it if the number guessed is too high, too low, or correct. The program works fine when the user just types a one character response, but freaks out when there is more than one character in "response". So I would like to limit the response to just one character. How do I do this?
Thanks
#include <stdio.h>
#include <string.h>
int main() {
char response[1];
int numOfGuesses = 1;
int min = 0;
int max = 100;
int guess = (max+min)/2;
int end = 0;
do {
printf("%d) %d: (h)igh, (l)ow, or (c)orrect? ", numOfGuesses, guess);
if (scanf("%1s", response) == 1) {
printf("%s \n", response);
if (strlen(response) > 1) {
printf("D'oh! Wrong response!! \n");
} else {
if (response[0] == 'h') {
max = guess;
numOfGuesses++;
} else if (response[0] == 'l') {
min = guess;
numOfGuesses++;
} else if (response[0] == 'c') {
printf("Correct! It took %d turns. \n", numOfGuesses);
end = 1;
} else {
printf("D'oh! Wrong response! \n");
}
guess = (max+min)/2;
}
} else {
end = 1;
}
} while ( end == 0 );
return 0;
}
Your response buffer is not null terminated, which pretty much makes it explode at
if (strlen(response) > 1) {
Make it response[2].
Alternatively, you can use %c in scanf instead of %1s.
Edit:
Try calling this function after every scanf, it flushes the input buffer until the next newline, removing any invalid input after the first char.
void flush_input()
{
int c = 0;
do
{
c = getchar();
} while (c != EOF && c != '\n');
}
If you're just looking for a single character input, why not use getchar() instead of scanf()?
Here's a page that discusses getchar() in more detail and has some usage examples, if you're interested: http://rabbit.eng.miami.edu/class/een218/getchar.html
Are you getting extra points for saving memory?
#include <stdio.h> up top, then declare response to be a large-ish array: char response[BUFSIZ];
You should initialize it before the loop, just because it's a good habit: *response='\0';
As you're not doing much, you could call gets(response) instead of scanf(). This will read in the entire line entered. Modern compilers and/or run-times will whine about the gets() as it can run off the end of the provided array (which is what your scanf() was doing), suggesting fgets() instead. The more-correct snippet becomes:
fgets(response, sizeof response, stdin);
use
if (scanf("%2s", response) == 1) {
instead of
if (scanf("%1s", response) == 1) {
this makes the compiler read up to 2 characters instead of just 1 at a time

Resources