printing a paragraph using putchar() - c

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

Related

C: Unknow size input with scanf()

I'm trying to make a simple program where you put some text in it and it write back what you just wrote.
For example if I write "Hello World", the program should write me back "Hello World"
How I think it should work is like that :
loop to check if the current character is '\0'
if not print the current character and reallocate 1 more byte of memory
else stop the loop
So it's looks like an easy thing to do but my attempt is not working correctly, for example if you put only a few characters it is going to write you back with no problem but with longer string.. it is not working at all.
I know it is possible using fgets(), but I would like to understand why my version with scanf() isn't working.
(my code)
#include <stdio.h>
#include <stdlib.h>
int main(void){
int mem = 2;
char * str = malloc(mem);
scanf("%s", str);
while (*str != '\0') {
printf("%c", *str);
realloc(str, mem++);
str++;
}
free(str);
return 0;
}
edit : I was thinking that I only did a small mistake but, after reading the comments it looks like there is a lot of things that I did wrong in this tiny program. I'm going make sure that I better understand how C work and retry to do this program later. Thanks for the help!
Your program could be much more simple
#include <stdio.h>
int main() {
char c;
while( scanf("%c", &c) == 1 ) {
printf("%c", c);
}
return 0;
}
If you're going to use scanf for this, you shouldn't use "%s". (You should never use "%s" without a field width, since this will potentially overflow a buffer. Using "%s" is no better that gets().) If you are going to use a variant of "%s", you need to understand that it will ignore whitespace. The following does almost what you want, except for the whitespace issue. If you want to handle whitespace with precision, you cannot use "%s".
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
void * xrealloc(void *buf, size_t num, size_t siz, void *endvp);
int
main(void)
{
size_t cap = 2;
char *end = NULL;
char *str = xrealloc(NULL, cap, sizeof *str, &end);
/*
* Read 1 char at a time, discarding whitespace. This should
* be done with getchar(). If using scanf, a single char
* should be read with "%c". We use "%1s" here only
* because the question is specifically about `%s`.
* Note that %1s will allow scanf to write up to 2 characters into
* *end, so we need to ensure there is space for the terminator.
*/
while( 1 == scanf("%1s", end++) ){
while( end > str + cap - 2 ){
str = xrealloc(str, cap *= 2, sizeof *str, &end);
}
}
fputs(str, stdout);
free(str);
return 0;
}
void *
xrealloc(void *buf, size_t num, size_t siz, void *endvp)
{
char **endp = endvp;
char *b = buf;
ptrdiff_t offset = b && endp && *endp ? *endp - b : 0;
b = realloc(b, num * siz);
if( b == NULL ){
perror("realloc");
exit(EXIT_FAILURE);
}
if( endp != NULL ){
*endp = b + offset;
}
return b;
}
Reading functions' manuals and searching for similar questions is a great method to get things clearer, and undestand the problem you are facing better :)
Try looking at this question: Reading input of unknown length, and particularly at this answer that uses scanf: scanf answer (I did not verify if that works, but it teaches you another method you can use).

Delay output till EOF rather than newline

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.

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.

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);
}
}

read string of character and assign it to an array

I don't know how to work with scanf and get the input of it for the entry of the function readBigNum I want to make array until the user entered the Enter and also I want to write a function for assigning it into an array and return the size of the large number
I want readBigNum to exactly have the char *n but I can not relate it in my function
#include <stdio.h>
int readBigNum(char *n)
{
char msg[100],ch;
int i=0;
while((ch=getchar())!='\n')
{
if(ch!='0'||ch!='1'||ch!='2'||ch!='3'||ch!='4'||ch!='5'||ch!='6'||ch!='7'||ch!='8'||ch!='9')
return -1;
msg[i++]=ch;
}
msg[i]='\0';
i=0;
return i;
}
int main()
{
const char x;
const char n;
n=scanf("%d",x);
int h=readBigNum(&n);
printf(h);
}
If I understand your question correctly, you want to implement a function that will read numbers from stdin storing them in a buffer. If a non-number is encountered, you want to return -1. If a new-line is encountered, you want to return the number of characters that were read. If that's correct, you'll probably want your code to look something like the following:
#include <stdio.h>
int readBigNum(char* n)
{
char ch;
int i=0;
while ((ch = getchar()) != '\n') {
if (ch < '0' || ch > '9') {
return -1;
}
n[i++] = ch;
}
n[i] = '\0';
return i;
}
int main(void) {
char buf[100];
int bytes = readBigNum(buf);
printf("%s\n", buf);
printf("%d\n", bytes);
};
The main differences from your implementation
The array to be populated is initialized in main and passed to the readBigNum function. This is a little simpler than having the function control the memory, in which case you would need likely need to deal with malloc and free. Even with this, you run the risk of a buffer overrun and will likely want to take additional precautions to prevent that.
The function does not set i to 0 before returning it. The original code could never return a value other than -1 (on error) or 0, which didn't appear to be the intent.
This code doesn't use scanf. Given your description of what you wanted to accomplish, using scanf didn't appear to be a good fit, however if you provide more information on why you were calling it might help to inform this answer.
The printf call was incorrect, it has been updated to print the number of bytes returned, and an additional printf call was added to print the updated buffer.
Remember that getchar() returns type int, not char. This is because the function may return EOF (which is defined as a negative integer with no particular value).
Also, for functions that deal with buffers, it is always a good idea to take an extra argument that describes the size of the array. This helps reduce buffer overruns because you know how far you can go. With your existing function, if the user types more than 100 characters, your buffer is overrun.
#include <stdio.h>
#include <ctype.h>
int readBigNum(char *n, size_t len)
{
int ch;
int i = 0;
// we make sure 'i' is less than 'len - 1' to leave space for '\0'
while((ch = getchar()) != EOF && i < (len - 1))
{
if (ch == '\n') // stop on linefeed
break;
else if (!isdigit(ch))) // abort on invalid character
return -1;
else
n[i++] = (char) ch;
}
msg[i] = '\0';
return i;
}
int main(void)
{
char buf[100];
int result = readBigNum(buf, sizeof buf);
if (result > 0)
printf("Length %d : %s\n", result, buf);
else
printf("Invalid number!\n");
}

Resources