Having installed Eclipse and CB, I encountered several projects that do not start properly. I assumed that it was because of the OS I used, that is why I switched to Ubuntu. However, some programmes I had tried to run still would not work correctly. For instance, this code from clc-wiki outputs nothing upon pushing Enter:
#include <stdio.h>
#define MAXLINE 40 /* maximum input line size */
int getlines(char line[], int maxline);
void copy(char to[], char from[]);
/* print longest input line */
int main()
{
int c;
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getlines(line, MAXLINE)) > 0) {
if (line[len-1] != '\n')
while ((c = getchar()) != EOF && c != '\n')
++len;
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) { /* there was a line */
printf("Longest line with %d characters:\n", max);
printf("%s ...\n", longest);
}
return 0;
}
/* getline: read a line s, return length */
int getlines(char s[], int lim)
{
int c, i;
for (i = 0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
The similar problem is faced, if we run it in XP. Nevertheless, everything is perfect, if we compile the very same code in ideone.
gcc and g++ are installed, as well as mingw for Windows.
Could you please tell me what the problem can be all about?
this code outputs nothing upon pushing Enter
That is the correct behavior of your code. It is designed to print nothing upon pushing Enter.
That code, in particular, requires an end-of-file indication. If your program reads from a file (as is the case on ideone), the end-of-file indication happens more-or-less automatically. If your program reads from the computer keyboard (as when you run it interactively), then you must provide an end-of-file indication.
To exercise the code you provided:
On Linux, from the keyboard, enter several lines of varying lengths, each followed by Enter. Then enter CONTROL-D on a line by itself.
On Windows, from the keyboard, enter several lines of varying lengths, each followed by Enter. Then enter enter CONTROL-Z on a line by itself.
Related
I've just started to read K&R and on pages 32-33, there is a code that
finds the longest line among the inputs.
I nearly completely copy-pasted the code given in the book, just added some comment lines to make the code more understandable for me. But it isn't working.
Edit: I'm sorry for bad questioning. It seems the program does not act properly when I press Ctrl + Z, in order to terminate it. No matter how many lines I type and how many times I press Ctrl + Z, it just does nothing.
The following is my version of the code:
/* Find the longest line among the giving inputs and print it */
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getLine(char line[], int maxLine);
void copy(char to[], char from[]);
int main(void) {
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here*/
max = 0;
/* getLine function takes all the input from user, returns it's size and equates it to the variable len
* Then, len is compared whether it's greater than zero because if there's no input, no need to do any calculation
* EDGE CASE
*/
while ((len = getLine(line, MAXLINE)) > 0)
/* If the length of input is larger than the previous max length, set max as the new length value and copy that input */
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line, EDGE CASE */
printf("%s", longest);
return 0;
}
/* Read a line into s, return length.
* Since the input length is unknown, there should be a limit */
int getLine(char s[], int lim) {
int c, i;
/* The loop's first condition is whether the input length is below the limit. EDGE CASE
* If it's not, omit the rest because it would cause a BUFFER OVERFLOW. Next, take the input as long as it's not an EOF command.
* Finally, if the input is end of line, finish the loop, don' take it.
*/
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
s[i] = c;
if (c == '\n')
s[i++] = c;
s[i++] = '\0'; // always put a '\0' character to a string array ending, so that the compiler knows it's a string.
return i;
}
void copy(char to[], char from[]) {
int i = 0;
// This loop is readily assigns all chars from the source array to the target array until it reaches the ending char.
while ((to[i] = from[i]) != '\0')
++i;
}
Thanks in advance!
Okay, here's the error:
s[i++] = '\0'; // always put a '\0' character to a string array ending, so that the compiler knows it's a string.
This will cause it to terminate the string even for no input (when it got EOF directly), and since it increments i before returning it, getLine() will never return 0 and thus main() will never stop. Removing the ++ fixed it, for my simple test.
Also, the comment is misleading, the compiler doesn't know anything. The compiler is no longer around when the code runs; the in-memory format of strings is something that's needed to keep the run-time libraries happy since that's what they expect.
Hi i am writing a program to count the number of lines the user enters, i have this code:
#include <stdio.h>
#include <string.h>
int readline(char line[], int max);
/* count lines in input */
main() {
int c, nl,max, i;
max = 99;
char line[100];
nl = 0;
while (( readline(line, max) != 0)){
++nl;
}
printf("%d\n", nl);
}
/* readline: read a line from standard input, return its length or 0
*/
int readline(char line[], int max)
{
if (fgets(line, max, stdin) == NULL)
return 0;
else
return strlen(line);
}
but i am not sure how to terminate the program and have "nl" printed to the screen, i am using the cygwin64 terminal to write and execute the program.
Thanks
size_t n;
while(fgets(line,max,stdin))
{
n = strlen(line);
if( n == 1 && line[n-1] == '\n')
{
//This is a empty line
}
}
Basically fgets() comes with a newline character and you can use this to confirm whether there was any input in the line or just a newline character was entered.
readline returns the text of the line read. A blank line returns
the
empty string. If EOF is encountered while reading a line, and the line
is empty, NULL is returned. If an EOF is read with a non-empty line,
it is treated as a newline.
So you can check for empty string.
Change the condition into like this,
while (( readline(line, max) <= 1)){
...
}
When you enter the empty new line then that new line will be placed in that array.
So it gives the strlen as 1.
I compiled the below program:
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print the longest input line */
main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
I tried to run it in bash shell:
gcc -o longest-line longest-line.c
./longest-line
And basically it turns into a running process (shows in result of ps aux) and the cursor just blinks. In the code, when the program is run and the getline function is called, it does 1000 iterations and the getchar is called each time to get input from the terminal in order to increment the counter if it's not end of file or newline. However, immediately there is no input in the terminal and when I start adding input and press the enter key:
$ ./longest-line
Hello World
Hello Again
Nothing happens. It's supposed to print the longest line.
The problem is that if you press '\n' from keyboard getline will always return 1 because of this statement
if (c == '\n') {
s[i] = c;
++i;
}
and the line while ((len = getline(line, MAXLINE)) > 0) will always be true.
But if you use a file as standard input it will work fine because of the EOF.
If you want it to work from keyboard input press Ctrl-D or Ctrl-Z to simulate an EOF.
So, on my compiler, I had to fix a few minor issues.
Generally, main should be written as int main() { ... } or int main(int argc, char **argv) { ... }.
getline() conflicts with a builtin function that gets pulled in from the #include <stdio.h>, so I simply renamed yours to getline_custom and also renamed all the usage points.
That being said, with these minor fixes, (which may not be required under your compiler), your program works correctly.
I believe your confusion is that the program won't print the longest line until after you've sent EOF. In bash, you can do this with CTRL+D.
Example:
[12:39pm][wlynch#watermelon /tmp] ./foo
test // Then I hit enter
longest line // Then I hit enter
short line // Then I hit enter
one more // Then I hit ctrl-D
longest line // This is output from the program.
Another Example:
If we use redirection, we can more easily see the difference between the input and output.
[12:42pm][wlynch#watermelon /tmp] printf "longest line\nshort line" | ./foo
longest line
or, using an input file:
[12:53pm][wlynch#watermelon /tmp] cat input.txt
longest line
short line
foo
blah
[12:53pm][wlynch#watermelon /tmp] cat input.txt | ./foo
longest line
On the other hand
If, on the other hand, you'd like the program to print the current longest line after each line of input, then we would need to change the code in this program.
Here's an example of that:
int main() {
int len = 0; /* current line length */
int max = 0; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
while ((len = getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
printf("Current longest line: %s", longest);
}
}
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);
}
}
Go ahead and look to the bottom of this post for the actual question
I may be trying to understand the really simple things a bit too much, but I just cannot continue until I figure this out.
While reading K&R 1.9 Character Arrays, you come across an example program which takes input and determines which line was the longest, then it reprints it.
In order to understand the getline function of this program, I have modified it slightly to print some information during its progression. Now I have found some input which, once I understand, should greatly enhance my understanding of getchar().
On a side note, when I try to read source code from the libraries I get completely overwhelmed. For example I tried hunting down getchar() and ended up staring dumbfounded at a tower of 18 #endif somewhere on line 300ish of stddef.h. I am going to save that headache by discontinuing the pursuit of functions in stdio.h for the near future. Is it normal that the libraries are extremely hard to find something? Shouldn't the function exist as readable source, or do I just have my hopes up?
I will just go ahead and post the entire modified program from K&R for convenience sake:
#include <stdio.h>
#define MAXLINE 5 /* maximum input line length */
int getline(char line[], int maxline);
void copy(char to[], char from[]);
/* print the longest input line */
main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
if (len > max) {
max = len;
copy(longest, line);
}
if (max > 0) /* there was a line */
printf("%s\n", longest);
printf("INFO: max = %d\n", max);
printf("INFO: sizeof s[] = %d", sizeof longest);
return 0;
}
/* getline: read a line into s, return length */
int getline(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i){
s[i] = c;
printf("INFO: s[%d] = %c\n", i, c);
if (c == '\n') {
printf("INFO: %d\n", i);
printf("INFO: s[%d] = \\n\n", i);
s[i] = c;
++i;}
}
s[i] = '\0';
return i;
}
/* copy: copy ’from’ into ’to’; assume to is big enough */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
Here is some example input/output: I am using CodeBlocks and Windows 7
Finally, my question is why does the for loop in the getline() function leave the loop after it gets to F and therefore places the null terminator after F as \0
My hypothesis is that perhaps putting the EOF character shown as ^Z in the windows terminal, the array is truncated to a length of 4 characters plus a null terminator. It turns out if I put the EOF character inside a line to be read, the saved line s[] will only contain a maximum size of 5. What also confuses me is that the variable len will always be 0, is that because len is assigned during the while loop in main(), and does not have its value saved once that while loop is broken?
Something interesting to me, but probably not to experienced C users, is that the if statement right after the for loop in getline() can either be inside the for loop, or outside and it does not change the program. Interesting, because won't that mean that whether or not the for loop executes any code in the body, at the very least (c=getchar()) is executed?
Sorry the question is so wordy, I appreciate any helpful comments/answers.
Because MAXLINE is 5, and the getline function never reads more than MAXLINE - 1 characters.