Delay output till EOF rather than newline - c

I am writing a program that copies input to output character by character on Linux terminal. The code is as follows (from Dennis Ritchie's C book)
#include <stdio.h>
/* copy input to output; 2nd version*/
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
The program and its execution works fine. But I want a slight modification.
The output appears on terminal for each new line character (when I press enter). I want to delay the output till I signal the end of file by pressing Ctrl + D. What modifications I have to do for the program in-order to delay my output on terminal.
Sample output I am getting is as follows:
abcd (enter)
abcd
llefn;elnf(enter)
llefn;elnf
(ctrl+d)
Sample output I wants to get is as follows:
abcd(enter)
llefn;elnf(ctrl+d)
abcd
llefn;elnf

You need to store these character's to buffer, control indexes where are you writing and when you receive EOF just print that buffer via printf.
If you cant solve it you can inspire here
#include <stdio.h>
#define BUFFER_SIZE 1024
int main()
{
int c, i = 0;
char buffer[BUFFER_SIZE];
while ((c = getchar()) != EOF)
{
if (i < BUFFER_SIZE - 1)
{
buffer[i] = c;
i++;
}
else
{
buffer[BUFFER_SIZE - 1] = '\0';
printf("%s", buffer);
i = 0;
}
}
buffer[i] = '\0';
printf("%s", buffer);
return 0;
}

An easy, albeit sloppy and partial solution is to configure stdout to fully buffered with a large buffer:
#include <stdio.h>
int main(void) {
int c;
setvbuf(stdout, NULL, _IOFBF, 32767);
while ((c = getchar()) != EOF) {
putchar(c);
}
return 0;
}
Notes:
On a 32- or 64-bit system, you could make the buffer ridiculously large.
Passing NULL to setvbuf lets it allocate the buffer with malloc().

As already mentioned in the comments: put the characters into a buffer and display the whole buffer at the end:
#include <stdio.h>
#define BUF_SIZE 1024
int main()
{
char str[BUF_SIZE]; // the buffer
int c, i = 0;
while (i < BUF_SIZE-1 && (c = getchar()) != EOF)
str[i++] = (char) c;
str[i] = '\0';
printf("%s\n", str); // display the contents of the buffer
}

You could set buffer to stdout with setvbuf(3).
#include <stdio.h>
main()
{
int c;
char buf[BUFSIZ];
setvbuf(stdout,buf,_IOFBF,BUFSIZ);
while ((c=getchar())!=EOF)
putchar(c);
}
The key here is the fully buffered mode specified with the _IOFBF constant.
The size of the buffer is set to BUFSIZ which usually equals 8192.
As was correctly pointed in the comments by Jonathan Leffler the limited size of the buffer may cause the program to suddenly spit out its contents garbling the terminal. To avoid that one could track the utilization of the buffer and extend its size when it gets filled.

Related

How to read multiple lines of string from stdin in C?

I am a novice in C programming. Suppose I want to read multiple lines of string from stdin. How can I keep reading until a line only containing EOL?
example of input
1+2\n
1+2+3\n
1+2+3+4\n
\n (stop at this line)
It seems that when I hit enter(EOL) directly, scanf won't execute until something other than just EOL has been entered. How can I solve that problem?
I'll be really grateful if someone can help me with this. Thank you.
If you want to learn C, you should avoid scanf. The only use cases where scanf actually makes sense are in problems for which C is the wrong language. Time spent learning the foibles of scanf is not well spent, and it doesn't really teach you much about C. For something like this, just read one character at a time and stop when you see two consecutive newlines. Something like:
#include <stdio.h>
int
main(void)
{
char buf[1024];
int c;
char *s = buf;
while( (c = fgetc(stdin)) != EOF && s < buf + sizeof buf - 1 ){
if( c == '\n' && s > buf && s[-1] == '\n' ){
ungetc(c, stdin);
break;
}
*s++ = c;
}
*s = '\0';
printf("string entered: %s", buf);
return 0;
}
to read multiple lines of string from stdin. How can I keep reading until a line only containing EOL?
Keep track of when reading the beginning of the line. If a '\n' is read at the beginning, stop
getchar() approach:
bool beginning = true;
int ch;
while ((ch = getchar()) != EOF) {
if (beginning) {
if (ch == '\n') break;
}
// Do what ever you want with `ch`
beginning = ch == '\n';
}
fgets() approach - needs more code to handle lines longer than N
#define N 1024
char buf[N+1];
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
; // Do something with buf
}
If you need to read one character at a time then you can with either getchar or fgetc depending upon whether or not you're reading from stdin or some other stream.
But you said you were reading strings, so I'm assuming fgets is more appropriate.
There are primarily two considerations:
maximum line length
whether or not to handle Windows versus non-Windows line endings
Even if you are a beginner--and I won't go into #2 here--you should know you can defend against it. I will at least say that if you compile on one platform and read from stdin from a redirected file from another platform, then you might have to write a defense.
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main (int argc, char *argv[]) {
char buf[32]; // relatively small buf makes testing easier
int lineContinuation = 0;
// If no characters are read, then fgets returns NULL.
while (fgets(buf, sizeof(buf), stdin) != NULL) {
int l = strlen(buf); // No newline in buf if line len + newline exceeds sizeof(buf)
if (buf[l-1] == '\n') {
if (l == 1 && !lineContinuation) {
break; // errno should indicate no error.
}
printf("send line ending (len=%d) to the parser\n", l);
lineContinuation = 0;
} else {
lineContinuation = 1;
printf("send line part (len=%d) to the parser\n", l);
}
}
printf("check errno (%d) if you must handle unexpected end of input use cases\n", errno);
}

Extreme troubles with full line input. C Programming Language

I am having the absolute craziest time getting full line input to work. I will explain my problem. I need to get a full line of input, including a space, from the user entered at the keyboard. Simple right? Wrong!
MY GOAL
Store multiple strings, with spaces, into variables. If it makes a difference, I want to make the variables equal to a char pointer. So once I get the input from tempString, I want to set it to a char pointer. Like so:
char *variable1, *variable2;
//get user input
variable1 = tempString;
//get more user input
variable 2 = tempString;
//etc etc etc
Here's what I've tried.
First try
char tempString[100];
scanf("%s", &tempString);
printf("%s", tempString);
Invalid: scanf will stop reading at a white space, so "Example String" would just end up being "Example".
Second try
So I do more research. I thought I found the magic fix.
char tempSTring[100];
fgets(tempString, 100, stdin);
printf("%s", tempString);
Originally this works. However there is a massive problem. I need to get the user to enter about 8 inputs. Meaning I have to use a command like this 8 times. The problem is the program often skips over the fgets command. If I use a scanf previously, somehow the \n character is stuck in the input stream, and automatically feeds into fgets, satisfying its stdin input, and then does not prompt the user for input.
Third try
After thinking fgets was maybe my solution with a work around, I tried some tricks.
char tempSTring[100];
getc(stdin);
fgets(tempString, 100, stdin);
printf("%s", tempString);
I tried adding this getc(stdin) line. It worked for much of my program. It absorbs the \n character left behind in the stream. When it does so, great, it works. But sometimes, for some reason, the \n is NOT left in the stream, and when debugging, it looks like getc(stdin) is requesting input from the user, so it pauses my program to ask for input.
Question
These don't work for me.
How should I be doing this easy task?
To read (up to) 8 lines from a file, you can use either of these solutions. I decline to use variables char *variable1, *variable2, …; — that is an array seeking to escape.
POSIX getline()
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char *buffer = 0;
size_t buflen = 0;
while (index < MAX_LINES && getline(&buffer, &buflen, stdin) != -1)
{
lines[index++] = buffer;
buffer = 0;
buflen = 0;
}
free(buffer); // Space may be allocated before EOF is detected
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
If getline() fails to allocate memory, it will report an error, so there is no need to do an explicit error check.
Standard C fgets()
Code using strdup(), another POSIX function. It isn't a part of standard C (though it is widely available). It is trivial to implement.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
enum { MAX_LINES = 8 };
char *lines[MAX_LINES];
int index = 0;
char buffer[4096];
while (index < MAX_LINES && fgets(buffer, sizeof(buffer), stdin) != 0)
{
if ((lines[index] = strdup(buffer)) == 0)
break;
index++;
}
for (int i = 0; i < index; i++)
printf("%d: %s", i, lines[i]);
return 0;
}
The test in the loop allows for the possibility of strdup() failing to allocate memory.
Notes
Both the solutions above keep the newline at the end of the input string. If you don't want that, you can zap it with:
lines[i][strcspn(lines[i], "\r\n")] = '\0';
This overwrites a carriage return or newline with a null byte, transforming DOS or Unix line endings. You then need to adjust the printing which assumes the string includes a newline. Note that the expression shown works correctly even if there is no carriage return or newline in the string.
The fgets() solution will break lines at 4095 characters, leaving the rest to be read as 'the next line'. If that's not acceptable, you have a variety of strategies open to you.
You can detect whether there is a newline and arrange to allocate more memory and read the next section of the line into the extra memory, repeating until you come across a newline or EOF.
You can read the remaining characters up to the newline or EOF:
int c;
while ((c = getchar()) != EOF && c != '\n')
;
Implementing strdup()
If for some reason your system doesn't have an implementation of strdup(), you can create a surrogate with:
#include <assert.h>
#include <stdlib.h>
#include <string.h>
char *strdup(const char *old_str)
{
assert(old_str != 0);
size_t old_len = strlen(old_str) + 1;
char *new_str = malloc(old_len);
if (new_str != 0)
memmove(new_str, old_str, old_len);
return new_str;
}
Here's how we old fart C programmers would do it:
#include <stdio.h>
#define MAX_LEN 100
int main( )
{
int c;
char input[MAX_LEN+1];
int i = 0;
while ( (c=getchar()) != '\n' && c != EOF && i < MAX_LEN)
input[i++] = c;
if (c == EOF || c =='\n') {
/* received input that terminated within buffer limit */
input[i] = '\0';
printf("read in your input string of: %s\n", input);
}
else {
printf("don't buffer overflow me dude!\n");
return -1;
}
return 0;
}
But nowadays people will tell you to use one of the library functions. I'm still an old fart though.
EDIT: Fixed my embarrassing mistakes pointed out by the helpful comments below.
You can take care of '\n' left by previous scanf by writing it like this -
scanf("%d%*c", &x); //<-- example to take int input
%*c will read from stdin and then discard it, thus '\n' would be removed from stdin.
You can achieve with scanf like this (a way for your previous attempt)-
char tempString[100];
/* As suggested by chqrile it is essential to check return of scanf */
if(scanf("%99[^\n]", tempString)!=1){
// ^^ & not required
tempString[0]='\0';
}
%99[^\n] this will read 99 characters and will stop only after encountering '\n' , thus would read input with spaces.

Writer inserting unwanted newline character

I have 2 C functions that interact with one another. The first a writer function takes an int n and writes "Hellohello" n number of times. The reader function reads whatever is input to it, and every 50 characters inserts a newline character.
My current dilemma is that when I have a number of characters that is a factor of 50 my reader is putting an extra newline character in when I do not want it to. I have tried multiple different ways to remedy this and nothing I have attempted has worked as of yet. What I'm providing is my reader code without any of my attempted fixes as well as an example of what the problem is.
I do have to use getchar and putchar, I understand that there would be easier ways if I wasn't using them but it is unfortunately a must. Any assistance as to how I should approach this or something I should have thought about are greatly appreciated.
reader code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count = 0;
char c;
while (c != EOF)
{
c = getchar();
if (count == 50)
{
putchar('\n');
count = 0;
}
putchar(c);
count++;
}
}
example output:
[88] [cbutc1#courses2016:~/csc412]$ writer 10 | reader1
HellohelloHellohelloHellohelloHellohelloHellohello
HellohelloHellohelloHellohelloHellohelloHellohello
▒[89] [cbutc1#courses2016:~/csc412]$
edit: clarity
When you read (getchar) a newline you print a newline (putchar).
Also, 'c' should be declared 'int'' so it is big enough to hold EOF properly.
Also the value of 'c' is undefined the first time through the loop and you print "EOF'", use:
while ((c = getchar()) != EOF) { …
Additionally, you should use int main ( void ) { …
And the C language does have "classes", only functions.
Simply changed the if statement that was checking the count to include a check for newline characters. This remedied the problem that was occuring.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count = 0;
char c;
while (c != EOF)
{
c = getchar();
if ((count == 50) && (c != '\n'))
{
putchar('\n');
count = 0;
}
putchar(c);
count++;
}
}

print multiple lines by getchar and putchar

Im a beginner learning The C Programming language and using Microsoft visual C++ to write and test code.
Below program in C from text(section 1.5.1) copy its input to its output through putchar() and getchar():
#include <stdio.h>
int main(void)
{ int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;}
The program print characters entered by keyboard every time pressing ENTER.As a result,I can only enter one line before printing. I can't find a way to enter multi-line text by keyboard before printing.
Is there any way and how to let this program input and output multi-line text from keyboard?
Sorry if this is a basic and ignorant question.
Appreciate your attention and thanks in advance.
Some clever use of pointer arithmetic to do what you want:
#include <stdio.h> /* this is for printf and fgets */
#include <string.h> /* this is for strcpy and strlen */
#define SIZE 255 /* using something like SIZE is nicer than just magic numbers */
int main()
{
char input_buffer[SIZE]; /* this will take user input */
char output_buffer[SIZE * 4]; /* as we will be storing multiple lines let's make this big enough */
int offset = 0; /* we will be storing the input at different offsets in the output buffer */
/* NULL is for error checking, if user enters only a new line, input is terminated */
while(fgets(input_buffer, SIZE, stdin) != NULL && input_buffer[0] != '\n')
{
strcpy(output_buffer + offset, input_buffer); /* copy input at offset into output */
offset += strlen(input_buffer); /* advance the offset by the length of the string */
}
printf("%s", output_buffer); /* print our input */
return 0;
}
And this is how I use it:
$ ./a.out
adas
asdasdsa
adsa
adas
asdasdsa
adsa
Everything is parroted back :)
I've used fgets, strcpy and strlen. Do look those up as they are very useful functions (and fgets is the recommended way to take user input).
Here as soon as you type '+' and press enter all the data you entered till then is printed. You can increase the size of array more then 100
#include <stdio.h>
int main(void)
{ int c='\0';
char ch[100];
int i=0;
while (c != EOF){
c = getchar();
ch[i]=c;
i++;
if(c=='+'){
for(int j=0;j<i;j++){
printf("%c",ch[j]);
}
}
}
return 0;
}
You can put a condition on '+' char or whatever character you would like to represent print action so that this character is not stored in the array ( I have not put any such condition on '+' right now)
Use setbuffer() to make stdout fully buffered (up to the size of the buffer).
#include <stdio.h>
#define BUFSIZE 8192
#define LINES 3
char buf[BUFSIZE];
int main(void)
{ int c;
int lines = 0;
setbuffer(stdout, buf, sizeof(buf));
while ((c = getchar()) != EOF) {
lines += (c == '\n');
putchar(c);
if (lines == LINES) {
fflush(stdout);
lines = 0;
}}
return 0;}
Could you use the GetKeyState function to check if the SHIFT key is held down as you press enter? That was you could enter multiple lines by using SHIFT/ENTER and send the whole thing using the plain ENTER key. Something like:
#include <stdio.h>
int main(void)
{ int c;
while (true){
c = getChar();
if (c == EOF && GetKeyState(VK_LSHIFT) {
putchar("\n");
continue;
else if(c == EOF) break;
else {
putchar(c);
}
}

printing a paragraph using putchar()

Consider the following code:-
#include"stdio.h"
void main()
{
char ch;
while((ch=getchar())!=EOF)
{
putchar(ch);
}
}
Whatever input I give to (as a sentence) it is repeated after I hit return key. What should I do if I want to get the entire paragraph at the end ? Can this be done using putchar() because putchar() can be used only to return a single character.
This won't work, since EOF doesn't fit in a char. Note that the proper return type of getchar() is int. See for instance this manual page.
If you want to read in a whole line at once, you can use fgets() into a character buffer for instance. I'm not sure I'm understanding exactly what you want to achieve, though.
EOF should be used when reading from files as the files end with a special EOF(end of file) character.You need to use any sentinel here to represent end of input.
this program makes a very little sense and I cant picture the use of this anywhere. So rethink about the requirements and change the logic accordingly.
may this code help you
char *buffer;
int i = 255;
buffer = (char *)malloc(i*sizeof(char));
*buffer = getchar();
while ( *buffer != '?' )
{
buffer++;
*buffer = getchar();
}
Try to store your char into a buffer and the when quit the while loop print the buffer. Try this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int c;
char *buf = calloc(1,sizeof(char));
int len;
while ((c=getchar())!=EOF) {
len = strlen(buf);
buf = realloc(buf, len+1);
buf[len] = (char) c;
buf[len + 1] = '\0';
}
printf("%s",buf);
}
If you want to get entire paragraph at end, you should store the input in a buffer while EOF reaches. then print content of buffer in a loop. Also as Mr. Unwind's answer says make, ch variable a int, char is wrong!
#include"stdio.h"
#define SIZE 1024
void main()
{
int buffer[SIZE]
int ch;
int i=0;
// Read and store in a buffer
while((ch=getchar())!=EOF)
{
buffer[i] = ch;
i++;
}
buffer[i] = EOF;
// now print using putchar(ch);
i = 0;
while((ch = buffer[i]) !=EOF)
{
putchar(ch);
i++;
}
}
cose all we did in console/terminal - until we dont hit Enter/Return/^J/^M shell not send line to our program
u can get paragraph(more then 1 line) by copy and paste some lines so terminal|console program show 1st u pasted then repeated - output of u program

Resources