Getchar() keeps returning 1 - c

i am new to StackOverflow. I hope to be able to learn a lot here.
So, i'm a beginner in C. I'm just trying a few things, like using very basic functions.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{ int c;
int i,wl[20];
int count = 0;
i = 0;
printf("Insert line: ");
while(c= getchar() != '\n'&& c != EOF)
printf("integer value of the variable is %d\n", c);
return 0;
}
This should be an easy program: you insert an input and gives you the current value in int.
The problem is: getchar keeps returning 1, no matter what.
Also, i have another question. I know that char in C is basically an 8 bit integer and as a matter of fact you can using char and int (with some problems, as integer are not 8 bit variables) interchangeably. So: why do some people declare a variable as int instead of char when in need to store a char with getchar? Sorry for such basic questions.
N.B: other variables are declared as this is part of a bigger code. all the other parts of the code were put as code in order to test this (/* */).
Sorry for my English, i hope what i wrote is clear.

This:
c= getchar() != '\n'
is equivalent to
c = (getchar() != '\n')
so not at all what you meant. So the 1 is the result of the != comparison. You need
(c = getchar()) != '\n'

Related

Initialising a c with int as EOF and then using it for getchar()?

The title pretty much says it all. I have this code for the homework (sent by the lecturer) which is for a spellchecker and I do not see the reason for c being an int initialized with EOF and then using it for getchar()? This is new to me, thank you! (I do not have anything inside the while because it is my assignment to put code there and I got stuck at the question above)
int c = EOF;
while ((c = getchar()) && c != EOF) {
}
EDIT: I was told the EOF is just so that it doesn't enter the while if there is no input but doesn't make sense to me since if c doesn't use getchar the while is still unused
The initialization is not functionally required.
It has the nice attribute of having c with an initialized value. Useful for debugging and avoiding otherwise uninitialized object errors. But in this case, code could have been int c = 0;, int c;, int c = EOF;, .... with no functional difference.
int c = EOF;
while ((c = getchar()) && c != EOF) {
;
}
OP: I was told the EOF is just so that it doesn't enter the while if there is no input but doesn't make sense to me since if c doesn't use getchar the while is still unused
If there is no input, c = getchar() will assigned EOF to c, overwriting the EOF initialization of int c = EOF;. In this case, the loop body is not entered even without initialization.
Now the debate can move to "what should be done" as the initialization is not functionally required. This and many like issues are best resolved by your group's coding standards. Lacking a group standard, follow the lead of your customer (professor?). Lacking that lead, go for what is simply: int c;
while ((c = getchar()) && c != EOF) { is an anti-pattern as it stops the loop when end-of-file occurs or if a null character is read. #wildplasser The below is more common, but selection depends on your coding goals.
while ((c = getchar()) != EOF) {
OP: So far I've only initialized variables with char when using getchar(), thought it has to be a char.
int getchar(void); typically returns 257 different values, [0...UCHAR_MAX] and EOF. Saving that into a char loses information. Use int.

What's wrong with my C character and line counting program?

I was reading Kernighan Ritchie and there's this Character counting program, so I tried implementing
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c;
int i;
c = getchar();
while (c != EOF)
i= i + 1;
printf("%d",i);
}`
When I compile and run this code, after I enter some characters there's no output after that. No number is printed and I can't figure out why. The code looks fine. I also tried using scanf() but the same thing happened.
The next example was for counting lines in input and the same problem was there too.
In your code, when you're hitting
i= i + 1;
the initial value of i is indeterminate. So, the whole program invokes undefined behavior. You need to initialize i.
To elaborate, i being an automatic local variable, unless initialized explicitly, the content is indeterminate. Using an indeterminate value in this case will lead to UB.
That said, a char is not able to hold a value of EOF, change the type to int.
After that, you're wrong in the logic. getchar() is not a loop on it's own, you need to keep calling getchar() inside the while loop body to update the value of c, used in the condition check in while.
int main()
Good. Not main() and not void main(). Keep it this way.
{
char c;
Bad. getchar() returns an int.
int i;
Bad. Not initialised, value is indeterminate. You are going to increment -7445219, or perhaps a kidney pie, who knows.
c = getchar();
Ok you have read a single character.
while (c != EOF)
But you cannot compare it to EOF because EOF doesn't fit in a char.
i= i + 1;
Looks like you forgot to do something in the body of the loop. Something that is going to change c perhaps so that your loop has a chance to finish.
printf("%d",i);
It is recommended to add a newline to the last line of your output.
}
That's all folks.
You only need to add an inicialization for "i"
int i = 0;
You missed the initialization:
int i = 0;

Loop through user input with getchar

I have written a small script to detect the full value from the user input with the getchar() function in C. As getchar() only returns the first character i tried to loop through it... The code I have tried myself is:
#include <stdio.h>
int main()
{
char a = getchar();
int b = strlen(a);
for(i=0; i<b; i++) {
printf("%c", a[i]);
}
return 0;
}
But this code does not give me the full value of the user input.
You can do looping part this way
int c;
while((c = getchar()) != '\n' && c != EOF)
{
printf("%c", c);
}
getchar() returns int, not char. And it only returns one char per iteration. It returns, however EOF once input terminates.
You do not check for EOF (you actually cannot detect that instantly when getchar() to char).
a is a char, not an array, neither a string, you cannot apply strlen() to it.
strlen() returns size_t, which is unsigned.
Enable most warnings, your compiler wants to help you.
Sidenote: char can be signed or unsigned.
Read a C book! Your code is soo broken and you confused multiple basic concepts. - no offense!
For a starter, try this one:
#include <stdio.h>
int main(void)
{
int ch;
while ( 1 ) {
ch = getchar();
x: if ( ch == EOF ) // done if input terminated
break;
printf("%c", ch); // %c takes an int-argument!
}
return 0;
}
If you want to terminate on other strings, too, #include <string.h> and replace line x: by:
if ( ch == EOF || strchr("\n\r\33", ch) )
That will terminate if ch is one of the chars listed in the string literal (here: newline, return, ESCape). However, it will also match ther terminating '\0' (not sure if you can enter that anyway).
Storing that into an array is shown in good C books (at least you will learn how to do it yourself).
Point 1: In your code, a is not of array type. you cannot use array subscript operator on that.
Point 2: In your code, strlen(a); is wrong. strlen() calculates the length of a string, i.e, a null terminated char array. You need to pass a pointer to a string to strlen().
Point 3: getchar() does not loop for itself. You need to put getchar() inside a loop to keep on reading the input.
Point 4: getchar() retruns an int. You should change the variable type accordingly.
Point 5: The recommended signature of main() is int main(void).
Keeping the above points in mind,we can write a pesudo-code, which will look something like
#include <stdio.h>
#define MAX 10
int main(void) // nice signature. :-)
{
char arr[MAX] = {0}; //to store the input
int ret = 0;
for(int i=0; i<MAX; i++) //don't want to overrrun array
{
if ( (ret = getchar())!= EOF) //yes, getchar() returns int
{
arr[i] = ret;
printf("%c", arr[i]);
}
else
;//error handling
}
return 0;
}
See here LIVE DEMO
getchar() : get a char (one character) not a string like you want
use fgets() : get a string or gets()(Not recommended) or scanf() (Not recommended)
but first you need to allocate the size of the string : char S[50]
or use a malloc ( #include<stdlib.h> ) :
char *S;
S=(char*)malloc(50);
It looks like you want to read a line (your question mentions a "full value" but you don't explain what that means).
You might simply use fgets for that purpose, with the limitation that you have to provide a fixed size line buffer (and handle - or ignore - the case when a line is larger than the buffer). So you would code
char linebuf[80];
memset (linebuf, 0, sizeof(linbuf)); // clear the buffer
char* lp = fgets(linebuf, sizeof(linebuf), stdin);
if (!lp) {
// handle end-of-file or error
}
else if (!strchr(lp, '\n')) {
/// too short linebuf
}
If you are on a POSIX system (e.g. Linux or MacOSX), you could use getline (which dynamically allocates a buffer). If you want some line edition facility on Linux, consider also readline(3)
Avoid as a plague the obsolete gets
Once you have read a line into some buffer, you can parse it (e.g. using manual parsing, or sscanf -notice the useful %n conversion specification, and test the result count of sscanf-, or strtol(3) -notice that it can give you the ending pointer- etc...).

How to read -1 char from stdin?

I am really desperate trying to figure out how can I read char with value -1/255 because for most functions this means EOF. For example if I enter all characters from extended ASCII from low to high (decimal value) I end up with -1/255 which is EOF so I will not get it to array. I created small code to express my problem.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFERSIZE 1024
int main(void){
char c;
unsigned int *array = (unsigned int*)calloc(BUFFERSIZE,sizeof(unsigned int)), i = 0;
while (1){
c = fgetc(stdin);
if (c == EOF)
break;
array[i] = c;
i++;
}
array[i] = 0;
unsigned char *string = (unsigned char *)malloc(i);
for(int j = 0;j < i;j++)
string[j] = array[j];
free(array);
//working with "string"
return 0;
}
I could mode
if (c == EOF)
break;
like this
c = fgetc(stdin);
array[i] = c;
i++;
if (c == EOF)
break;
but ofcourse, program will read control character that user input from keyboard too (for example Ctrl+D - Linux). I tried opening stdin as binary but I found out that posix systems carries all files as binary. I am using QT, GCC and Ubuntu. I tried fread, read, fgets but I ended up the same. Simply said, I need to read everything I enter on stdin and put it into char array except when I enter control character (Ctrl+D) to end reading. Any advices appreciated.
Edit: As noted in the comment by #TonyB you should not declare c as char because fgetc() returns int, so changing it to int c; should make it possible to store EOF in c.
I didn't see that you declared c as char c; so all the credit goes to #TonyB.
Original Answer: Although the problem was addressed in the comments, and I added the solution to this answer, I think you are confused, EOF is not a character, it's a special value returned by some I/O functions to indicate the end of an stream.
You should never assume that it's vaule is -1, it often is but there is a macro for a reason, so you should always rely on the fact that these functions return EOF not -1.
Since there is no ascii representation for the value -1 you can't input that as a character, you can however parse the input string {'-', '1', '\0'}, and convert it to a number if you need to.
Also, Do not cast the return value of malloc().

C echo user input

So I am a very beginner to C programming (I have used Ruby, Python and Haskell before) and I am having trouble getting the most simple thing to work in C (probably because of all the manual memory stuff). Anyway, what I am trying to do is (using simple constructs) make a script that just echoes what the user inputs to the console.
e.g. user inputs hi, console prints hi.
This is what I came up with.
Also, I haven't really mastered pointers, so none of that.
// echo C script
int echo();
int main() {
echo();
return 0;
}
int echo() {
char input[500];
while (1) {
if (scanf("%[^\n]", input) > 0) {
printf("%s\n", input);
}
input[0] = 0;
}
return 1;
}
I realize that there is a bunch of bad practices here, like setting a giant string array, but that is just for simplifying it.
Anyway, my problem is that it repeats the first input then the input freezes. As far as I can tell, it freezes during the while loop (1 is never returned).
Any help would be appreciated.
Oh, and using TCC as the compiler.
You don't need an array for echo
#include <stdio.h>
int main(void)
{
int c;
while((c = getchar()) != EOF) putchar(c);
return 0;
}
It's fine that you have such a large string allocated, as long as it's possible for users to input a string of that length. What I would use for input is fgets (read this for more information). Proper usage in your situation, given that you still would like to use the string of size 500, would be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int echo(){
char input[500];
while(fgets(input, 500, STDIN)){ //read from STDIN (aka command-line)
printf("%s\n", input); //print out what user typed in
memset(input, 0, strlen(input)); //reset string to all 0's
}
return 1;
}
Note that changing the value of 500 to whatever smaller number (I would normally go with some power of 2 by convention, like 512, but it doesn't really matter) will limit the length of the user's input to that number. Also note that I didn't test my code but it should work.
scanf("%[^\n]", input
Should be:
scanf("%s",input)
Then after your if you should do:
memset(input,0,500);
There are many ways of accomplishing this task however the easiest would be to read from stdin one byte at a time and output that byte to stdout as you process each byte.
Snippet:
#include <stdio.h>
int main( void ) {
// Iterates until EOF is sent.
for ( int byte = getchar(); byte != EOF; byte = getchar() ) {
// Outputs to stdout the byte.
putchar( byte );
}
return 0;
}
Remark:
You must store the byte that you are reading through stdin in an integer. This is because you are not guaranteed that char is signed or unsigned, there are in fact 3 char types in C (char, signed char and unsigned char). Include the limits library to determine whether a char is signed or not in your environment.
You must compile using the C99 standards, otherwise move the declaration of byte outside of the for loop.

Resources