My instructions: Write a program that repeatedly (until end-of-file) reads in a character
from the input stream. If the character is upper case, change it to lower case
and write it to the output stream. For all other characters, write the
character unchanged to the output stream.
Use getchar() for input, Use putchar() for output, and use input redirection
for connecting the input file to the program
My project name is Input and my textfile is input.txt. When I run it I type "Input < input.txt" The program just mimics that on the command window though so how do I get it to read from the text file?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
char c, x;
c=getchar();
while (c != EOF)
{
c=getchar();
x = tolower(c);
if (isupper(c))
{
putchar(x);
}
else
{
putchar(c);
}
}
system("Pause");
}
I believe the problem is that you do not want to go to the program and type in Input < input.txt. Instead, you want to open a terminal program, change directory into the directory containing the project, and then run the program from the command line by writing Input < input.txt. This starts up the program and uses the contents of input.txt as the standard input stream, rather than reading text from the console.
That said, there are two bugs in your code. First, note that you have the line
c = getchar();
outside of your loop that does the input reading. You then immediately call
c = getchar();
again inside the loop. This means that you are discarding the very first character that you read in.
Second, your loop runs one more time than it needs to. If the second call to getchar() returns EOF, you do not detect this until after the current loop iteration finishes. This is because your check for EOF is at the top of the loop, which isn't reached until after you've already printed out the EOF character. To fix this, consider using the loop-and-a-half idiom and breaking out of the loop in the middle:
for (;;) {
/* Read data. */
if (/* no data left */) break;
/* Process data. */
}
Stylistically, are you sure that you need both the if and else branches here? Recall that tolower will not change the values of characters that aren't upper-case, so having one case for upper-case letters and one for lower-case is redundant. You can just output the character produced by tolower without the special cases.
Hope this helps!
The idiomatic way of doing this for ASCII text only is:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
int c;
while((c = getchar()) != EOF)
putchar(tolower(c));
exit(EXIT_SUCCESS);
}
As textbooks are so fond of saying, UTF-8 is left as an easy exercise to the reader ;-)
Related
I have trouble understanding getchar() and EOF.
I was trying to run this code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c;
int a = 0; //no. of characters
while (1) {
c = getchar();
if (c == EOF) {
// printf("%i",c);
break;
}
putchar(c);
++a;
}
printf("%i", a);
int b;
while ((b = getchar()) != EOF) {
putchar(b);
}
printf("here"); // to check wether the code written after the loop is executed
}
I terminated the first loop by pressing Ctrl-D twice, I found many posts explaining the reason for this. But whenever I try to call the getchar() function after the first loop it keeps returning EOF, even though that would have been already read by the last call in the first loop.
Code editor - VSCode
OS - macOS
You must define c as an int to accommodate for the full range of possible return values from getchar(), namely all values of type unsigned char and the special negative value EOF (usually defined as (-1)).
On most unix systems, when Ctrl-D is typed in the terminal in canonical mode, whatever input has been buffered by the terminal is sent to the process. In your case, it causes the input to be echoed. If there is no such input pending, the terminal sends zero bytes to the process, which is interpreted by the OS as the end of file. Hitting Ctrl-D twice in a row, or more precisely at the beginning of a read request, does not enter an EOF byte, it signals the end of file to the reading process, hence any further attempt at reading from the stream will return EOF immediately without requesting more user input from the terminal.
Just started on K&R and hit:
#include <stdio.h>
/* copy input to output; 1st version */
main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
And it just displays what I input, even if it's a string of text.
cacti
cacti
stop repeating what i'm saying
stop repeating what i'm saying
Just like that.
What I don't get is why I can't just instantiate variable c with a string of text and print it the same way. (Ignoring the while loop for the sake the example) Like with:
main()
{
int c;
c = "cacti";
putchar(c);
}
Wherein the output is apparently just 'd'
Here c is only integer which take a character for your case(Although its limits are larger than that).
For first code segment:
getchar() only return a character and you use while loop which take a character from stream and through putchar() it print to console until end of file. You seems to get a line of string and print it but it don't do that way.
In second code segment:
You put a const char* to integer which is not valid(My gcc 4.9.2 does not compile). So it show undefined character (Why print 'd' I don't know, may be compiler issue).
You can do this by:
main()
{
char c[] = "cacti";
puts(c);
}
EDIT
According to getchar() definition:
On success, the character read is returned (promoted to an int value).
The return type is int to accommodate for the special value EOF, which indicates failure.
When you type a single line and press enter then first character read outside of while loop. Than check if it is EOF(End Of File- No more data on the file . You can give EOF by pressing Ctrl+Z in windows and Ctrl+D in linux).
As if it is not encountered EOF, then it entered in while loop and print the singe character(by putchar(c)). After the next line c=getchar() take another character you entered in previous line and check while loop condition while(c!=EOF) being true it entered into loop and print a character. It continues until there found any character to print.
So it makes confuse with puts() which Writes a string in standard output.
Where putchar() Writes a character to the standard output.
According to http://www.cplusplus.com/
Writes the C string pointed by str to the standard output (stdout) and appends a newline character ('\n').
You could use a line-oriented input function to read whole lines. For example:
#include <stdio.h>
int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != 0)
fputs(line, stdout);
return 0;
}
For most plausible files, this will read one line at a time into the array of characters, and then write that line out. (If the line length is longer than 4095 characters, then lines will be processed in multiple segments.) If the file contains null bytes, then the material from the null byte to the end of line will be ignored. There are fixes for that — see standard C functions fread() and fwrite(), and POSIX function
getline().
Note that your second example:
int main(void)
{
int c;
c = "cacti";
putchar(c);
}
shouldn't compile without warnings about assigning a character pointer to an integer. When you use putchar() on the result, it probably prints the least significant byte of the address where the string "cacti" is stored. It is pure coincidence that the character printed is d.
The putchar() function only ever prints a single byte (which means a single character in many code sets, but it might only be part of a character in UTF-8).
I want to read a stream of characters from standard input whose length is unknown. I am trying to read character by character as
#include <stdio.h>
int main(void)
{
char ch;
do
{
scanf("%c",&ch);
//do some comparison of ch
}while(ch!='');
return 0;
}
Help me write the condition in while so that I can read input properly without entering into an infinite loop
Sample input:
abcdefghijklmnop
Probably a simplest form of solution will be this
#include <stdio.h>
int main(void)
{
char ch;
do
{
ch = fgetc(stdin);
//do some comparison of ch
}while( ch != EOF );
return 0;
}
But having said that, problem statement like below
read a stream of characters from standard input whose length is
unknown
is a bit tricky. As per the program above is concerned you can probably stop it with a ctrl+d, EOF or run the binary with file redirection
./a.out < input.txt
in fact, the interpretation of standard input is what makes this question more meaningful.
Your escape character is wrong.
Your want to write everything on one line ? Then use '\n' to end your loop.
while (ch != '\n')
If you write character by character, use one to exit your sequence (for exemple '#')
while (ch != '#')
I'm working through "The C Programming Language" by K&R and example 1.5 has stumped me:
#include <stdio.h>
/* copy input to output; 1st version */
int main(int argc, char *argv[])
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
I understand that 'getchar()' takes a character for 'putchar()' to display. However, when I run the program in terminal, why is it that I can pass an entire line of characters for 'putchar()' to display?
Because your terminal is line-buffered. getchar() and putchar() still only work on single characters but the terminal waits with submitting the characters to the program until you've entered a whole line. Then getchar() gets the character from that buffer one-by-one and putchar() displays them one-by-one.
Addition: that the terminal is line-buffered means that it submits input to the program when a newline character is encountered. It is usually more efficient to submit blocks of data instead of one character at a time. It also offers the user a chance to edit the line before pressing enter.
Note: Line buffering can be turned off by disabling canonical mode for the terminal and calling setbuf with NULL on stdin.
Yeah you can actually write whatever you want as long as it's not an EOF char, the keyboard is a special I/O device, it works directly through the BIOS and the characters typed on the keyboard are directly inserted in a buffer this buffer is, in your case read by the primitive getchar(), when typing a sentence you are pushing data to the buffer, and the getchar() function is in an infinite loop, this is why this works.
You can ask me more questions if you want more details about how the IO device work.
Cheers.
Consider the following program,
This program gets the input (getchar runs) till we enter '$' character and prints the output.
#include <stdio.h>
int main()
{
int c;
while ((c = getchar()) != '$')
putchar(c);
return 0;
}
If we enter input as abcd$$$$$$[Enter], it stores the input in buffer till the last $ symbol. After we pressed enter, the program (while loop) starts to run and getchar function receives one character at a time and prints it, from 'a' till first '$' .
And the program won't end till we press '$' in the input.
in the example:
#include <stdio.h>
main()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
I don't quite understand it. putchar() would put the character out, but why is it that after EOF it puts all the characters out, and where is it remembering all these characters? Thanks.
It's called buffering and it's done by the operating system. Usually it does line buffering where it just saves every character you put to it in memory, and then writes it all to the file when it encounters a line break. This saves on resources because file operations take much more time than other operations. So instead of doing output with every single character, it waits for a bunch of characters to collect in the buffer and writes them out all in one go.
It's just a clever maneuver done by the OS that you, the programmer, don't need to worry about. Just throw your characters at it one by one and let the OS handle the rest in its own way.
[This isn't an answer, but you can't put code in the comments]
I think you meant something like this:
#include <stdio.h>
main()
{
long nc;
nc = 0;
char c;
while ((c = getchar()) != EOF)
{
putchar(c); /* prints one char */
++nc;
}
printf("%ld\n", nc); /* prints the number of characters read */
}
No where, this code only empty the input and write how many caracters where left before the flush.
This is to be sure that the is no caracters remaining in the input file (stdin)
putchar put the char into the buffer when it comes an enter ,then it will bring the line word output to the screen.