Problem in Example 1.9 - The C Programming Language - c

I have tried to compile and run the program below which is the example 1.9 of the book The C Programming Language. It is compiled OK and no errors are found. However, when I run it and see if the program works, instead of returning me the longest line, it returns a sequence of garbage characters with the same length of the longest line.
Here is the program:
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
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;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i] != '\0')) {
++i;
}
}

This expression:
(to[i] = from[i] != '\0')
is not doing what you think. It will compare from[i] != '\0' first, and assign the result to to[i]. This means the destination string will be the correct length but full of characters with code 1.
So probably you copied the parenthesis in the wrong position:
(to[i] = from[i]) != '\0'

Related

Conflicting types for 'function'

I'm learning C with "The C programming language" book. And I'm stucked with this error.
Here is the code:
#include <stdio.h>
#define MAXLINE 1000 // Max input line length
int getline(char line[], int maxline);
void copy(char to[], char from[]);
// Printing the longest input line
int main()
{
int len; // Current line length, max line length ever seen
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while((len = getline(line, MAXLINE)) > 0)
{
if(len > max) // If current line length > previous max length - rewrite.
{
max = len;
copy(longest, line);
}
}
if(max > 0) // If there was a line
printf("%s", longest);
return 0;
}
int getline(char s[],int lim) // return length of line
{
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;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while((to[i] = from[i]) != '\0')
++i;
}
This code is an example from the book :)
Trying to compile it on Linux: Linux 5.4.97-gentoo.
GCC version: 10.2.0.
getline is already declared in <stdio.h>. Change the method name to my_getline.

C: find the longest line

This is an example program from the book The C Programming Language by Dennis Ritchie and Brian Kernighan (Second Edition). My question is if we are passing the value(variable line) but not the reference to the function length, then how does the change reflect in the main function?
#include <stdio.h>
#define MAXLINE 1000
int length(char s[], int lim);
void copy(char to[], char from[]);
int main() {
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = length(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) {
printf("%s", longest);
}
return 0;
}
int length(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;
}
void copy(char to[], char from []) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
}
This definition:
int length(char s[], int lim)
can be rewritten as:
int length(char *s, int lim)
which might make it easier to understand. We don't pass the variable by value, we pass the pointer, so the function can access the data and modify it if necessary.
len = length(line, MAXLINE)
in C all arrays are passed by pointer. so the function length receives the pointer to first char oh the array line and it modifies this array

Can't print out a string in C

I've been learning C with a book and I tried one of its programs on my Linux PC with gcc, but for some reason it doesn't work.
#include <stdio.h>
#define MAXLINE 1000
int getoneline(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int line_length, max_length;
char line[MAXLINE];
char longest[MAXLINE];
max_length = 0;
while ((line_length=getoneline(line, MAXLINE)) > 0)
if (line_length > max_length)
{
max_length = line_length;
copy(longest, line);
}
if (max_length > 0)
printf ("%s", longest);
return 0;
}
int getoneline(char s[], int limit)
{
int c, i;
for (i=0; i < limit - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while((to[i] = from[i]) != '\0')
++i;
}
It is the same in the book and it's supposed to find the longest line in some text and the output it. However, nothing gets outputted, as if the variable longest disappeared after the while loop. I can print it inside, though, but that's not what I want.
What's going wrong?
Works for me! Try running the program and entering a few lines of text. Then press Ctrl-D so that getchar returns an EOF, causing the program to break out of the while loop and print the longest line
I would point out that there are about a million better ways to write this code that are less confusing. Without getting into all the reasons for this, I sincerely recommend following the 'get a new book' advice in the comments.

K&R 1.19 exercise ("reverse" func)

Here is the task:
Write a function reverse(s) that reverses the character string s . Use it to write a program that reverses its input a line at a time.
Ok, now, my performing:
#include <stdio.h>
#define LIM 40
char line[LIM];
int c;
int reverse(char line[], int lim);
int len;
int main(void) {
while ((len = reverse(line, LIM)) > 0) {
;
}
printf("\n END OF THE PROGRAM \n");
return 0;
}
********** THE REVERSE FUNCTION*********
int reverse(char s[], int lim) {
char rev[LIM];
int 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';
int r;
for (r = 0; r < lim - 1; ++r) {
rev[r] = s[i];
--i;
}
int x;
for (x = 0; x < lim - 1; ++x) {
putchar(rev[x]);
}
printf("\n");
return r;
}
It seems to work correctly, but there are some bugs related to the output.
For example:
INPUT: hello everybody OUTPUT: ydobyreve olleh
INPUT: abc OUTPUT: cba'
INPUT: ABC OUTPUT: CBA'
INPUT: ABC ABC OUTPUT: CBA CBA
INPUT: se se OUTPUT: es es'
See? Some strange " ' " occurs in the end of output and I can't figure out any pattern why these "artifacts" get printed. It happens randomly (for me). Could you please suggest anything, what's wrong in the code?
Your reverse function has problems:
You should not store the newline into the s array as you do not want it to take part in the reverse operation.
You should stop the subsequent for loop when you reach the end of the string in s, not run all the way to the end of the buffer.
You should null terminate the rev array.
You do not need to output the rev array one character at a time, use is as a string.
Here is a corrected and simplified version:
#include <stdio.h>
#define LIM 40
int reverse(char line[], int size);
int main(void) {
char line[LIM];
int len;
while (reverse(line, LIM) > 0) {
continue;
}
printf("\n END OF THE PROGRAM \n");
return 0;
}
/* THE REVERSE FUNCTION */
int reverse(char s[], int size) {
char rev[size];
int i, r, c, len;
for (i = 0; i < size - 1 && (c = getchar()) != EOF && c != '\n'; i++) {
s[i] = c;
}
len = i;
s[i] = '\0';
for (i = 0; i < len; i++) {
rev[len - i - 1] = s[i];
}
rev[i] = '\0';
printf("%s\n", rev);
return len;
}
A bit more modular solution. I wasn't exactly sure what K&R meant by "one line at a time". But this will reverse the string until it finds a newline. Then wait for the user and repeat.
#include <stdio.h>
#define MAXLINE 1000
int get_line(char s[], int limit);
int reverse(char to[], char from[], int l);
int main() {
int size;
char line[MAXLINE];
while ((size = get_line(line, MAXLINE)) > 0) {
char revline[size];
int len = reverse(revline, line, size);
printf("%s\n", revline);
}
return 0;
}
int reverse(char to[], char from[], int l) {
int i;
int j = l - 2;
for (i = 0; i < l; i++, j--) {
to[i] = from[j];
}
to[i] = '\0';
return i;
}
// read a line into s until limit
// return length of line
int get_line(char s[], int limit) {
int c = 0;
int i = 0;
for (i = 0; i < limit-1 && (c = getchar()) != '\n'; ++i) {
s[i] = c;
}
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
Output:
testing one two
owt eno gnitset
three four
ruof eerht
five six
xis evif

What is the output on ubuntu terminal with smal box of zeros and one?

Here is my code in c.
I compiled and run it on ubuntu terminal and the maximum length(max) is printed out but not the string(longest) - it just outputs a small box with zero and one.
I am a beginner in programming.
Thank you
#include<stdio.h>
#define MAXLINE 1000
int my_getline(char line[], int maxline);
void copy(char to[], char from[]);
main() {
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = my_getline(line, MAXLINE)) > 0) {
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0)
printf("%d\t %s \n",max, longest);
return 0;
}
int my_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;
}
void copy(char to[], char from []) {
int i;
i = 0;
while ((to[i] == from [i]) != '\0')
++i;
}
Your copy routine doesn't copy anything. Probably you mean to use = instead of ==.
To my taste these ideas of using assignments inside control expressions is a really bad habit that buys you nothing but trouble. Something like
for(;;) {
to[i] = from[i];
if (to[i]) ++i;
else break;
}
would be clearer.
Inside your copy routine, you want assignment, not comparison:
void copy(char to[], char from []) {
int i;
i = 0;
while ((to[i] = from [i]) != '\0')
++i;
}
You need to re-implement your copy routine as it is not getting anything. A simple solution is as following:
strcpy(to, from);
You need to include string.h and call this instead of your copy function. If you want to implement sting copy yourself, use the following:
void copy(char * to, char * from) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i++;
}
to[i] = '\0';
}
You need to be sure that string to is at least the same size of string from.

Resources