Word wrap in C

How to word wrap in terminals

Page 1 of 1

10 Replies - 10525 Views - Last Post: 05 June 2010 - 04:38 PM Rate Topic: -----

#1 Guest_Lars*


Reputation:

Word wrap in C

Posted 03 June 2010 - 08:31 PM

Hi there. I'm working on a little project that I'm going to release for several systems. I need help on how to write a simple word wrap function. The console can be everything from 18 characters wide and upwards.

I'd like to make a function for this myself, but after an hour of searching for a C word wrap function (that I can understand and is usable), I decided to come for help. Obviously, the function needs to be able to work with different terminal widths, as I'm releasing it for several platforms.

At first I thought I could use strtok, puts and a variable which contains remaining line space, but I can't seem to get it to work. I should mention that I'm a newbie to C, but not a newbie to programming, so I understand the concepts.

Could anyone provide some sample code, or some help on how to write a simple word wrap function that takes a string and a terminal width as arguments?

It would be hugely appreciated.

Thanks alot in advance,
Lars

Is This A Good Question/Topic? 0

Replies To: Word wrap in C

#2 Skaggles  Icon User is offline

  • THE PEN IS MIGHTIER
  • member icon





Reputation: 251
  • View blog
  • Posts: 640
  • Joined: 01-March 09

Re: Word wrap in C

Posted 03 June 2010 - 09:19 PM

One way of doing this is to use the insert function of strings. It will place a string at a specified point within another string: str.insert(5, "\n"); is a way to insert in a line break at the position of 5 within the string str. All you need to do is utilize a for loop, jumping through a string every X spaces (determined by your width) and place a "\n" at that point. Of course, there's a little more error checking involved, but I'm sure you can handle things from this point. Hope this helped!

This post has been edited by Skaggles: 03 June 2010 - 09:26 PM

Was This Post Helpful? 0
  • +
  • -

#3 Guest_Lars*


Reputation:

Re: Word wrap in C

Posted 04 June 2010 - 03:52 AM

View PostSkaggles, on 03 June 2010 - 08:19 PM, said:

One way of doing this is to use the insert function of strings. It will place a string at a specified point within another string: str.insert(5, "\n"); is a way to insert in a line break at the position of 5 within the string str. All you need to do is utilize a for loop, jumping through a string every X spaces (determined by your width) and place a "\n" at that point. Of course, there's a little more error checking involved, but I'm sure you can handle things from this point. Hope this helped!

Hi Skaggles, and thanks for your reply. I can't find any reference to the "str.insert" function whatsoever, maybe you're confusing it with C++ or C#? I'm writing this in pure, portable C with the standard libraries, and portability is important.
Was This Post Helpful? 0

#4 janotte  Icon User is offline

  • code > sword
  • member icon

Reputation: 990
  • View blog
  • Posts: 5,141
  • Joined: 28-September 06

Re: Word wrap in C

Posted 04 June 2010 - 03:58 AM

View PostLars, on 04 June 2010 - 07:52 PM, said:

I can't find any reference to the "str.insert" function whatsoever,


You are correct that it is a C++ string class method and not included in "vanilla" C.

There are some C methods to look at here
http://www.cplusplus...ibrary/cstring/

But given the fact that in C strings are simple character arrays then a solution that replicates the Skaggles simple and brutal approach to wrapping should be simple to work out.

What I am wondering is what spec requirements are you working to?
What do you mean by "simple word wrap"?
Do you want to break at spaces or at a fixed line length or some other requirement?
Without a requirement statement that spells out what is to be achieved it is very hard to give you meaningful help.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5826
  • View blog
  • Posts: 12,678
  • Joined: 16-October 07

Re: Word wrap in C

Posted 04 June 2010 - 04:03 AM

Take a line, look at the point you want to wrap it +1. If it's a space, print the line to that point. If not, backup until you hit a space or the beginning of the line. If it's a string that you can write to and don't care about, you can do it like this:
#include <stdio.h>
#include <stdlib.h>


int main () {
	int i;
	char s[] = "This is only a test for wrapping lines";
	printf("%s\n", s);
	i = 20; // our wrap point
	while(i!=0) {
		 if (isspace(s[i])) {
			 s[i] = '\n';
			 break;
		 }
		i--;
	}
	printf("\n%s\n", s);
	
	return 0;
}



This code as it stands isn't going to help all that much. You need to figure out how to repeat it for the length of the like. However, that's the idea.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#6 noclaf  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 26
  • View blog
  • Posts: 94
  • Joined: 18-April 10

Re: Word wrap in C

Posted 04 June 2010 - 12:47 PM

void print_wrapped(const char* buffer, size_t maxlength, int indent) {
  size_t count, buflen;
  const char *ptr, *endptr;

  count = 0;
  buflen = strlen(buffer);

  do {
    ptr = buffer + count;

    /* don't set endptr beyond the end of the buffer */
    if (ptr - buffer + maxlength <= buflen)
      endptr = ptr + maxlength;
    else
      endptr = buffer + buflen;

    /* back up EOL to a null terminator or space */
    while (*(endptr) && !isspace(*(endptr)) )
      endptr--;

    count += fwrite(ptr, 1, endptr - ptr, stdout);

    /* print a newline and an indent */
    printf("%-*s", indent, "\n");
  } while (*endptr);
}


Currently using this in one of my projects. I don't think it behaves properly when it encounters a word longer than the line length, but I haven't seen it break yet otherwise.

edit: fixed broken do/while.

This post has been edited by noclaf: 05 June 2010 - 12:39 PM

Was This Post Helpful? 0
  • +
  • -

#7 Guest_Lars*


Reputation:

Re: Word wrap in C

Posted 05 June 2010 - 12:33 PM

View Postnoclaf, on 04 June 2010 - 11:47 AM, said:

void print_wrapped(const char* buffer, size_t maxlength, int indent) {
  size_t count, buflen;
  const char *ptr, *endptr;

  count = 0;
  buflen = strlen(buffer);

  do {
    ptr = buffer + count;

    /* don't set endptr beyond the end of the buffer */
    if (ptr - buffer + maxlength <= buflen)
      endptr = ptr + maxlength;
    else
      endptr = buffer + buflen;

    /* back up EOL to a null terminator or space */
    while (*(endptr) && !isspace(*(endptr)) )
      endptr--;

    count += fwrite(ptr, 1, endptr - ptr, stdout);

    /* print a newline and an indent */
    printf("%-*s", indent, "\n");
}

Currently using this in one of my projects. I don't think it behaves properly when it encounters a word longer than the line length, but I haven't seen it break yet otherwise.

Hi there! Thanks for your helpful code, but it seems it's cut off at the end. You never close your do..while loop, so this doesn't compile.
Was This Post Helpful? 0

#8 noclaf  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 26
  • View blog
  • Posts: 94
  • Joined: 18-April 10

Re: Word wrap in C

Posted 05 June 2010 - 12:40 PM

View PostLars, on 05 June 2010 - 01:33 PM, said:

Hi there! Thanks for your helpful code, but it seems it's cut off at the end. You never close your do..while loop, so this doesn't compile.

Mm, so right you are... fixed in the last post.
Was This Post Helpful? 0
  • +
  • -

#9 Guest_Lars*


Reputation:

Re: Word wrap in C

Posted 05 June 2010 - 03:44 PM

View Postnoclaf, on 05 June 2010 - 11:40 AM, said:

View PostLars, on 05 June 2010 - 01:33 PM, said:

Hi there! Thanks for your helpful code, but it seems it's cut off at the end. You never close your do..while loop, so this doesn't compile.

Mm, so right you are... fixed in the last post.

Thanks a bunch mate, this works perfectly! :D
Was This Post Helpful? 0

#10 Guest_Lars*


Reputation:

Re: Word wrap in C

Posted 05 June 2010 - 03:46 PM

View PostLars, on 05 June 2010 - 02:44 PM, said:

View Postnoclaf, on 05 June 2010 - 11:40 AM, said:

View PostLars, on 05 June 2010 - 01:33 PM, said:

Hi there! Thanks for your helpful code, but it seems it's cut off at the end. You never close your do..while loop, so this doesn't compile.

Mm, so right you are... fixed in the last post.

Thanks a bunch mate, this works perfectly! :D

A little question though, it seems to indent by one space even when indent is set to 0? Not a dealbreaking issue, just thought I'd ask :)
Was This Post Helpful? 0

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5826
  • View blog
  • Posts: 12,678
  • Joined: 16-October 07

Re: Word wrap in C

Posted 05 June 2010 - 04:38 PM

There is an answer on the table and I have some issues with it. :P

To this end, I'll offer my own:
#include <stdio.h>
#include <stdlib.h>

void printwrap(const char *s, int lineSize, const char *prefix) {
	const char *head = s;
	int pos, lastSpace;
	
	pos = lastSpace = 0;
	while(head[pos]!=0) {
		int isLf = (head[pos]=='\n');
		if (isLf || pos==lineSize) {
			if (isLf || lastSpace == 0) { lastSpace = pos; } // just cut it
			if (prefix!=NULL) { printf("%s", prefix); }
			while(*head!=0 && lastSpace-- > 0) { printf("%c", *head++); }
			printf("\n");
			if (isLf) { head++; } // jump the line feed
			while (*head!=0 && *head==' ') { head++; } // clear the leading space
			lastSpace = pos = 0;
		} else { 
			if (head[pos]==' ') { lastSpace = pos; }
			pos++;
		}
	}
	printf("%s\n", head);
}

int main(){
	int i;
	char *text = "0        1         2         3\n12345678901234567890123456789012345678901234567890123456789012345678901234567890\nHi there.  I'm working on a                          little project that I'm going to release for several systems. I need help on how to write a simple word wrap function. The console can be everything from 18 characters wide and upwards.\n\nI'd like to make a function for this myself, but after an hour of searching for a C word wrap function (that I can understand and is usable), I decided to come for help. Obviously, the function needs to be able to work with different terminal widths, as I'm releasing it for several platforms.\n";
	printwrap(text, 30, ">\t");
	return 0;
}



It adresses a number of issues. It handles a line that's greater than line size with no spaces. It properly deals with new lines. It trims leading space. It doesn't call strlen and could reasonably be adapted to deal with a stream of unknown length.

This post has been edited by baavgai: 05 June 2010 - 04:39 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1