Copying the input from `getchar()` to another variable - c

In the following code example from K&R's book, if I replace putchar(c) with printf("%c", c) the code works the same. But if I replace it with printf("%d", c) it gives gibberish output.
#include <stdio.h>
int main() {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
From here, I learned that the getchar() converts the stdin to an 8-bit character whose value ranges from 0 to 255.
Now I want to print the value of c using putchar(c) in one line and printf("%d", c) in another line. So I wrote the following code:
#include <stdio.h>
int main() {
int c, b;
c = getchar();
b = c;
while (c != EOF && c != 10) {
printf("%c",c);
c = getchar();
}
printf("\n");
while (b != EOF && b != 10) {
printf("%d\t",b);
b = getchar();
}
}
I used the condition c != 10 as the newline character is read as 10 by getchar(). I expected the code to work as
$ ./a.out
783
783
55 56 51
but the program terminates as
$ ./a.out
783
783
55
I understand that getchar() takes input from stdin and the variable b is not stdin. So how should I copy the variable c to b so that my program works as I expect it to?

The problem is that your code does not (and cannot, as it stands) 'remember' the inputs you gave in the first loop. So, after you have finished that loop, your second loop is wanting to read in the characters for b (after it has output the first value, which is remembered from the earlier b = c line).
So, after outputting 55 (the integer value of the character 7), it is waiting for further input.
Probably the easiest way to get the output that you're looking for is to have an array of input characters. Then, you can output the %c values as you read them (as before), then re-run the outputs using the %d format in a subsequent for loop.
Here is a demonstration that does what I think you're after:
#include <stdio.h>
#define MAXINS 20 // Set to the maximum number of input characters you want to allow
int main()
{
int c[MAXINS];
int i = 0, n = 0;
c[0] = getchar();
while (i < MAXINS && c[i] != EOF && c[i] != 10) {
printf("%c", c[i]);
c[++i] = getchar();
++n;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf("%d\t", (int)(c[i]));
}
return 0;
}
Feel free to ask for further clarification and/or explanation.
EDIT: On the point in the your first paragraph, "But if I replace it with printf("%d", c) it gives gibberish output." Well, when I try the following code and give 783 and then hit return (which generates a newline) I get the expected 55565110 as the output:
int main()
{
int c;
c = getchar();
while (c != EOF) {
printf("%d", c);
c = getchar();
}
return 0;
}
This may look like gibberish, but it's just the same output as you 'expect' in your later code, but without the spaces and with the addition of the 10 for the newline.

You need to have every character stored, because once you read a char from stdin, it is not present in stdin anymore.
Since you want the newline character in the end as a part of the input, you should use fgets to take the input.
Say you are taking an input that could have a maximum of 100 characters.
#include <stdio.h>
int main(void) {
char c[100]; // A char array
fgets(c,100,stdin);
int x=0;
while (c[x] != 10 && c[x] != EOF)
printf("%c",c[x++]);
printf("\n");
x = 0;
while (c[x] != 10 && c[x] != EOF) // You can simply compare it with the newline character too.
printf("%d ",c[x++]);
printf("\n");
return 0;
}
There are many ways to do this. You can also read stdin character-by-character ans store it in an array. However, since you need to display the ASCII values of the characters in another line after displaying the characters themselves, you will have to store them in an array.

You are copying only the first input, to copy the whole string you need to store each input in a buffer and check if the string doesn't overflow that buffer on each iteration:
int main(void)
{
enum {size = 256};
char buffer[size];
size_t count = 0;
int c;
while ((c = getchar()) && (c != '\n') && (c != EOF))
{
printf("%c", c);
if (count < size)
{
buffer[count++] = (char)c;
}
}
printf("\n");
for (size_t iter = 0; iter < count; iter++)
{
printf("%d\t", buffer[iter]);
}
printf("\n");
}
If you don't want to limit the buffer to an arbitrary size then you need to change your approach to use dynamic memory (realloc or a linked list)

Related

What are the numbers associated with printing getchar()?

Code:
int main(void) {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
printf("%d", c);
}
}
I enter a character and that character is returned with putchar(c), however, if I print that character I get a code back? example:
0 = 48010
1 = 49110
2 = 50210
etc...
what are these numbers? is this where the character is stored in memory or something?
cheers
So I believe I figured out the problem by introducing newlines
int main(void) {
int c;
c = getchar();
while (c != EOF) {
putchar(c);
printf("\n");
c = getchar();
printf("%d\n", c);
}
}
When I enter 1 this returns the following in the terminal window.
49
1
10
What's happening is I'm returning the ASII character code for 1 - > 49
returning the value I entered with getchar()
and returning 10 which is the linefeed value i.e. the enter command.
Right? without the newlines it was just concatenating them all, making it confusing.

C beginner question: Array is not printing

I'm trying to produce a simple program which will read a string and print it along with the number of characters in it.
The character count seems fine, but it won't print the full string. For whatever reason, it will print only the second character. I have been reviewing my code and I still cannot figure out why this is happening.
If I input: abcdef
It will print out: 1
b 2
3
4
5
6
Instead of the intended: a 1 b 2 c 3 d 4 e 5 f 6
#include <stdio.h>
int main()
{
char c;
char str[0] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
c = str[i];
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Any help is appreciated. Thanks.
You have a variable str that is of zero length, and you try to access various elements in it (but it has none, so this is undefined behavior)
Just get rid of it and use c directly:
#include <stdio.h>
int main()
{
char c;
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
charcount++;
printf("%c %d \n", c, charcount);
}
return 0;
}
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This declaration
char str[0] = {};
is invalid with two respects. The array size shall be greater than zero. And the the braces that initialize the array shall not be empty.
In fact the array is redundant because what you are trying to do is just output entered characters.
This assignment
c = str[i];
does not make sense even if the array was be declared correctly because the entered character is overwritten by the (non-existent) element of the array.
The variable c itself should have the type int.
If you just need to perform this
I'm trying to produce a simple program which will read a string and
print it along with the number of characters in it.
then the program can look for example the following way
#include <stdio.h>
int main(void)
{
size_t i = 0;
for ( int c = getchar(); c != EOF && c != '\n' && c != '#'; c = getchar() )
{
++i;
printf( "%c %zu ", c, i );
}
putchar( '\n' );
return 0;
}
If to enter
abcdef
then the output will be
a 1 b 2 c 3 d 4 e 5 f 6
If you want to use a character array and store entered characters in the array then the program can look like
#include <stdio.h>
int main(void)
{
enum { N = 100 };
char s[N];
int c;
for ( size_t i = 0; i < N && ( c = getchar( ) ) != EOF && c != '\n' && c != '#'; i++ )
{
s[i] = c;
printf( "%c %zu ", s[i], i + 1 );
}
putchar( '\n' );
return 0;
}
The program output will be the same as above if to enter for example abcdef.
I took your question to mean you were looking to store the characters that are entered into an array and print them out as you go. You want to give the array an initial size (I chose 99) and then add characters to the array as you go. You can keep track of the length so you know where the "end" is. There are better ways to manage string data in C, but here you go.
#include <stdio.h>
int main()
{
char c;
char str[99] = {};
int i;
int charcount;
charcount = 0;
for (i = 0; (c = getchar()) != '#' && c != '\n'; i++) {
// c = str[i];
str[i] = c;
charcount++;
printf("%c %d \n", str[i], charcount);
//if(charcount > 80)
// printf("%d", z[i]);
}
return 0;
}
Some additional thoughts:
You probably want to look at something like string.h
If you are going to keep the char array, you need to protect against going over the size of the array
Adding a little blurb about what you expect your program to do, what the requirements are, example input, output, etc would have helped get better answers from the community

Why is this code printing a random character inbetween the input and output lines?

I'm trying to write a program (in C) where the input is reversed and printed in reverse line by line. For the most part, the code actually does just that. The trouble is that for some (most) of my input, I will get a random character or an extra newline in between my input and my output in the console.
For example, I start the program, type "testing" into the console, and get "gnitseT" back after hitting enter. This has happened successfully and is what I expect. It looks like this:
Testing
gnitseT
But then when I type "Hello" into the console, it looks like this:
Hello
g (unexpected)
olleH
Or if I type "running" into the console, instead of getting an unexpected "g" in between my input and output lines, I get an extra newline.
Running
newline here
extra newline here (unexpected)
gninnuR
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
i++;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
}
return 0;
}
The expected behavior is for the program to output into the console the reversed input after the enter key is pressed.
Sometimes, especially at the very beginning of the program, it will work perfectly.
Then, it starts giving me a random character in between my input and output, or it starts giving me an extra newline.
I would like to have it so that it just prints the input in reverse order without any unexpected odd characters showing up in between the input and the output.
Thanks for any help.
Your immediate problem is you are reading and attempting to print one character past the end of the characters stored in your array with
for (i = length; i >= 0; i--) {
printf("%c", s[i]);
}
Why? You add length characters to smain in main(). In C, arrays are zero-based. The characters in your string are from 0 -> length-1 (the nul-character in a string is located at s[length], but here you never add a nul-terminating character, so the value at that index is simply indeterminate). If the element has not been initialized (which it will not be on your first word or any subsequent word equal to or longer than your longest word entered at that time) Undefined Behavior results since you are attempting to read and print an indeterminate value from an uninitialized element in array. How your terminal will output the indeterminate is undefined -- and may well result in a G being printed.
To correct the problem, loop for (i = length - 1; i >= 0; i++) or very simply:
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
(note: don't call the variadic printf function to output a single-character, that is what putchar() is for)
Putting it altogether and fixing your logic so you don't add and print the '\n' as part of every word you are reversing, you could do:
#include <stdio.h>
#define MAXC 2048 /* if you need a constant, #define one (or more) */
void reverse(int length, char s[])
{
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
}
int main (void) {
char smain[MAXC];
int c, i = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
reverse(i, smain);
i = 0;
}
else
smain[i++] = c;
}
if (i) /* protect against file with no POSIX end-of-file */
reverse (i, smain);
return 0;
}
(note: the if {...} else {...} logic to prevent adding the '\n')
Example Use/Output
$ printf "Hello\nGoodbye\n" | ./bin/prnrevlines
olleH
eybdooG
Which will work just as well without the POSIX eof, e.g.
$ printf "Hello\nGoodbye" | ./bin/prnrevlines
olleH
eybdooG
on line 29
++i;
this means "i" now have length+1 so, you have been out of the string, you can change the program to :
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
else i++;
}
return 0;
}

Basic C programming

I'm trying to write a program which given a certain number of input will output the product of the listed input (only accounting inputs of 0-9 and ignoring other).
For example:
input:345 would result output: 60, or another example would be, input: 3t4 and output: 12
I have given it many attempts and this is what I'm stuck with :
#include <stdio.h>
main(){
int c,i;
c = getchar();
i = 1;
while (c!= '\n'){
if (c>=48 && c<=57){
i=c*i;
c=getchar();
}
}
printf("%d",i);
}
How can i do this ?
Couple of issues in your code.
After each time the program encounters a non-numeric character it doesn't read further from the input. It reads the same character. Hence c=getchar() should be outside the if block
The multiplication happens for the char variable c. It should be converted to the actual number and then be multiplied. In your code you are multiplying its ascii value. Hence (c-48)*i instead of c*i
Use i=(c-48)*i; instead of i = c*i. So, the changed program would be:
#include <stdio.h>
main(){
int c,i;
c = getchar();
i = 1;
while (c!= '$'){
// printf("%c\n", c);
if (c>=48 && c<=57){
i=(c-48)*i;
}
c=getchar();
}
printf("%d",i);
}
This will ensure that you are using the numeric value of the digit, 0 not as ascii code of 0 but as simple 0.
use c=getchar() outside the if block. This should work.
int i,c;
i = 1;
while (i){
c=getchar();
if(c == '\n')
{
break;
}
if (c < 48 || c > 57)
{
i = -1;
break;
}
i = i * (c-48);
}
if (i == -1)
{
printf("Error. Non-Number Entered\n\n");
}
else {
printf("%d\n\n",i);
}

Code prints out correctly with a leading space.

I'm new to C programming and I'm having probably a simple issue.
I've looked all over the site looking for an answer to this but my no luck.
So my program runs fine if at the end of the input file there is a space. For example running the program from command line in unix
./program-name < file.txt
if the file.txt is
//with a space whith | | being a space.
The Cat Ran.| |
I get the correct output 1 1 1
if it is
The Cat Ran.(With no space I get 1 1)
//I have to use C for this program.
#include <stdio.h>
int main(void){
int i=0;
char c;
int NOV=0;
while( (c=getchar())!=EOF && c !='\n' && c !=10 ){
if( c=='a'||c=='e'||c=='i'||c=='o'||c=='u' ){
NOV++;
}
if(c==' '){
printf("%d ",NOV);
NOV=0;
}
}
printf("\n");
return 0;
}
Any Help is appreciated.
The trouble is that when you get EOF without a space, you exit the loop, and nothing after the loop prints the number of vowels.
Add if (NOV != 0) printf("%d", NOV); after the loop, perhaps.
Separately, your use of 10 is odd; '\n' is control-J or 10. You might be thinking of control-M, aka carriage return or '\r'.
Also, as Blue Pixy pointed out in a comment, you should always use int c; to receive the return from getchar() or getc() of fgetc(). The functions return an int, which may be any value that fits in an unsigned char or EOF, a negative value. You run into problems if you use char c instead.
Your program should read like this (a lot of useless clutter has been removed) :
int main(void)
{
int c;
int nov = 0;
while( (c = getchar()) != EOF && c != '\n')
{
if( c=='a'||c=='e'||c=='i'||c=='o'||c=='u' )
nov++;
}
printf("%d\n", nov) ;
return 0;
}

Resources