0

I have my code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverseSentence();

int main(void){

int i = 0;
int lineLength = 0;
char string[100];

printf("Enter the output line length : \n");
scanf("%d", &lineLength);

printf("Enter your text (control-d to exit) : ");
reverseSentence();

return 0;

}

void reverseSentence(){

while(!feof(stdin)){
char c;
scanf("%c", &c);

if( c != '\n'){
  reverseSentence();
  printf("%c", c);
    }

   }
}

I need to have the string entered to be printed as such (see picture).

enter image description here

I can get the string to be printed backwards but I can not get it to print only 10 (or otherwise stated) characters long. How do I have the string output with only a line length of 10 characters?

Wilson Vargas
  • 2,841
  • 1
  • 19
  • 28
RollTide1234
  • 17
  • 1
  • 6
  • Why don't you catch all the string in one time ? It will be easier to parse it and get each x characters – YaatSuka Oct 04 '17 at 23:39
  • Before you print a word, make sure there is enough space on the line :) (Of course, that is not compatible with writing one character at a time. Probably that's the point of the exercise.) – rici Oct 04 '17 at 23:43
  • Note that [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). – Jonathan Leffler Oct 05 '17 at 00:19
  • This recursion example is terrible. In case the input is a flat text file of 50K text, the function will be called 50K times?!? – Krassi Em Oct 05 '17 at 04:50

2 Answers2

0

To keep using you're approach you're going to need to keep track of how many characters you printed in order to decide when you should print a new line, char count would be the input received from the user and the initial value of current count would be zero for the first call

void reverseSentence(int char_count, int current_count){

while(!feof(stdin)){
char c;
scanf("%c", &c);

if( c != '\n'){
    current_count++;
    if(char_count == current_count){
        printf("\n");
        current_count = 0;
    }
    reverseSentence(char_count, current_count);
    printf("%c", c);
    }

   }
}
Mitch
  • 3,342
  • 2
  • 21
  • 31
0

While I'm convinced that you are attempting to reverse a line of text rather than a sentence given,

Enter the output line length: 10
Enter your text (Enter to exit)

and your title "How to print output line length?", if you are looking solely for something that will check for the end of a sentence (e.g. a '.'), the following can be modified without much effort.

Where you are having problems looks to be "How do I know what the number of characters in the wrapped line is?" Which is required to know how many spaces to prefix each line of output by.

The key to any line wrap scenario is to basically use a sliding window to bracket the characters that fit in each wrap length of characters (accounting for spaces between words). Meaning, you have a wrap length, but that number of characters may end in the middle of a word, so you need to keep track of the last natural break (a space normally) that occurs before that number of characters is reached. (then output the words that fit).

Your next set or characters begins not at your current counter, but at the next non-space character following the words just printed. Your count for the next group of words to output begins there. You are effectively sliding a window of wrap length chars down your string, outputting the words that fit within your sliding window, then sliding the window to capture the next group of words.

Whether you reverse the words within the window is a relatively trivial matter. Either print from the beginning to the end of the window, or the end to the beginning.

The other aspect of your problem is figuring out how many spaces to prefix each reversed group of words by. That is where the number of characters within the window is important.

An easy way to handle both the window and the length is simply to use a pair of pointers. Setting your start pointer (say sp) to the beginning character in your windows, and your end pointer (say ep) to the last character in each word as you work your way down the string. When you reach your wrap length number of characters, you know you have ep - sp number of characters in the words to output. You then know you need wrap_length - (ep - sp) number of spaces to prefix your line.

Putting those concepts together, you can both wrap and reverse your input with something similar to the following:

 void str_word_wrap_rev (char *buf, int n)
{
    char *p = buf,   /* pointer to current char */
         *sp = buf,  /* pointer to start of line to print */
         *ep = buf;  /* pointer to end of line to print */
    size_t l = 0,    /* length of segment (no. of chars */
           pre = 0;  /* prefix - number of spaces */

    for (; *p && *p != '\n'; p++) { /* loop over each char (omit '\n')*/
        if (*p == ' ')              /* if space, set ep */
            ep = p;
        if (p - sp >= n) {          /* if limit from start reached */
            l = ep - sp;            /* compute number of characters */
            pre = n - l;            /* get leading spaces required */
            while (pre--)           /* output spaces */
                putchar (' ');
            while (l--)             /* loop over chars ep -> sp (reverse) */
                putchar (sp[l]);
            putchar ('\n');         /* tidy up with '\n' */
            sp = ++ep;              /* set start to next after end */
            ep = ++p;               /* set end to next after current */
        }
    }                       /* handle last line of chars */
    l = p - sp;             /* number of chars */
    pre = n - l;            /* number of spaces */
    if (*p == '\n')         /* if buf ends with '\n', decrement */
        p--;
    while (pre--)           /* output spaces */
        putchar (' ');
    while (p >= sp)         /* output chars */
        putchar (*p--);

    putchar ('\n');
}

(note: the function also checks for a string ending in '\n' to allow buf to be passed directly from one of the line oriented input functions, such as fgets or POSIX getline)

A short example similar to your example, could be:

#include <stdio.h>

#define MAXC 1000

void str_word_wrap_rev (char *buf, int n)
{
    char *p = buf,   /* pointer to current char */
         *sp = buf,  /* pointer to start of line to print */
         *ep = buf;  /* pointer to end of line to print */
    size_t l = 0,    /* length of segment (no. of chars */
           pre = 0;  /* prefix - number of spaces */

    for (; *p && *p != '\n'; p++) { /* loop over each char (omit '\n')*/
        if (*p == ' ')              /* if space, set ep */
            ep = p;
        if (p - sp >= n) {          /* if limit from start reached */
            l = ep - sp;            /* compute number of characters */
            pre = n - l;            /* get leading spaces required */
            while (pre--)           /* output spaces */
                putchar (' ');
            while (l--)             /* loop over chars ep -> sp (reverse) */
                putchar (sp[l]);
            putchar ('\n');         /* tidy up with '\n' */
            sp = ++ep;              /* set start to next after end */
            ep = ++p;               /* set end to next after current */
        }
    }                       /* handle last line of chars */
    l = p - sp;             /* number of chars */
    pre = n - l;            /* number of spaces */
    if (*p == '\n')         /* if buf ends with '\n', decrement */
        p--;
    while (pre--)           /* output spaces */
        putchar (' ');
    while (p >= sp)         /* output chars */
        putchar (*p--);

    putchar ('\n');
}

int main (void) {

    char buf[MAXC] = "";
    int n = 0;

    /* read/validate n */
    printf ("Enter the output line length: ");
    if (scanf ("%d%*c", &n) != 1) {
        fprintf (stderr, "error: invalid conversion for 'n'\n");
        return 1;
    }

    /* read/validate line using fgets for line-oriented input */
    printf ("Enter your text (Enter to exit)\n");
    if (!fgets (buf, MAXC, stdin) || *buf == '\n') {
        fprintf (stderr, "error: EOF or empty string\n");
        return 1;
    }
    putchar ('\n');

    str_word_wrap_rev (buf, n); /* reverse and wrap */

    for (int i = 1; i <= n; i++)
        putchar ('0' + i % 10);
    putchar ('\n');

    return 0;
}

Example Use/Output

$ ./bin/str_rev_wrap
Enter the output line length: 10
Enter your text (Enter to exit)
The quick brown fox jumps over the lazy old dog.

 kciuq ehT
 xof nworb
revo spmuj
  yzal eht
  .god dlo
1234567890

$ ./bin/str_rev_wrap
Enter the output line length: 25
Enter your text (Enter to exit)
The quick brown fox jumps over the lazy old dog.

spmuj xof nworb kciuq ehT
   .god dlo yzal eht revo
1234567890123456789012345

Look things over and let me know if you have further questions.

(note: It may help to simply write your input out on a piece of paper and draw the start, end and current character pointers below the string and move them manually to understand exactly what is taking place.)

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85