Hi all, I wanted to practice my beginner skills with a little text game, but I want a word wrap function to format the text properly. I found this one that looks promising, but I can't figure out how to use it.
/*
This function takes a string and an output buffer and a desired width. It then copies
the string to the buffer, inserting a new line character when a certain line
length is reached. If the end of the line is in the middle of a word, it will
backtrack along the string until white space is found.
*/
#include <string.h>
#include <ctype.h>
char* word_wrap (char* buffer, char* string, int line_width) {
int i = 0;
int k, counter;
while(i < strlen( string ) )
{
// copy string until the end of the line is reached
for ( counter = 1; counter <= line_width; counter++ )
{
// check if end of string reached
if ( i == strlen( string ) )
{
buffer[ i ] = 0;
return buffer;
}
buffer[ i ] = string[ i ];
// check for newlines embedded in the original input
// and reset the index
if ( buffer[ i ] == '\n' )
{
counter = 1;
}
i++;
}
// check for whitespace
if ( isspace( string[ i ] ) )
{
buffer[i] = '\n';
i++;
}
else
{
// check for nearest whitespace back in string
for ( k = i; k > 0; k--)
{
if ( isspace( string[ k ] ) )
{
buffer[ k ] = '\n';
// set string index back to character after this one
i = k + 1;
break;
}
}
}
}
buffer[ i ] = 0;
return buffer;
Can anyone tell me the correct usage for this code? I'm not sure what "buffer" is supposed to be when calling the function.
#include <stdio.h>
// your function
int main(void) {
// example message
constchar* message = "Testing 1 2 3 4 This is a message";
// buffer for storing the resultant string - make sure its large enough!
char buffer[40] = {0};
printf("Message:\n%s\n", word_wrap(buffer, message, 15));
return 0;
}
Message:
Testing 1 2 3 4
This is a
message
Note that you should really change the second parameter to take const char* rather than char* - otherwise the above example (shouldn't) compile due to the casting away of qualifiers.
Are you using C++ or C?
If you are using C++, its quite easy. Just use a std::string, and you can add variables to it, or you could use std::stringstream:
1 2
std::string room1 = "Your name is" + std::string(player_name) + " and you're super kewl!";
word_wrap(buffer, room1.c_str(), 20);
If you are using C, you should instead use snprintf, like this:
1 2
char message[256];
snprintf(message, 255, "Your name is %s and you're super kewl!", player_name);
Hi, I hate to bother you about this again, but I can't get the + operators to work. For example:
char buffer[3000] = {0};
const char* finalize = "Your name is " + string(player_name) + " and you're " + string(age) + " years old. You're a " + string(gender) + " and your body type is " + int(body) + ".";
cout << (word_wrap(buffer, finalize, 80);
Trying to use this spits out the following error:
error: no match for 'operator+' (operand types are 'std::basic_string<char>' and 'int')
Any ideas? I tried using finalize.c_str() as well, same error... can't get this working.
You are using char arrays, rather than std::string. I'm going to assume you are using C++ (from your error message). You need to use the to_string function to convert:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include <string>
//...
char buffer[3000] = {0};
/* Assuming:
std::string player_name;
int age;
std::string gender;
std::string body;
*/
std::string finalize = "Your name is " + player_name + " and you're " + std::to_string(age) +
" years old. You're a " + gender + " and your body type is " + body + ".";
word_wrap(buffer, finalize.c_str(), 80);
cout << buffer << '\n';
You'll also need to have a compiler with C++11 - VS is enable by default, for GCC or Clang you'll need to add it yourself (normally with -std=c++11).
I really appreciate your help, but I still can't get it to work even when copy/pasting verbatim. I'm going to post the entire code so far, maybe you could figure out what's wrong? I'm getting "to string is not a member of std." C++11 is enabled. Also, in this case age is handled as a string, and body is an int. When removing to_string and putting age as just "age", I get the same operator+ error from before.
Some compilers don't have the std::to_string function implemented yet for certain systems.
You can just make your own to_string function if you think you're running one of those:
1 2 3 4 5 6 7 8 9
// You'll need to #include <sstream>
// Just stick this at the top somewhere...
template <typename T>
std::string to_string(const T& x)
{
std::ostringstream oss;
oss << x;
return oss.str();
}
(If you end up using this one, make sure you don't use std:: when you call it)
Well... I'm unfortunately back again. I seem to have a never ending supply of problems getting this code to work the way I want it to. Here's the problem now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//Finalize character.
char finalize_B[3000] = {0};
std::string finalize_S = "Your name is " + player_name + " and you're " + age + " years old. You're a " + gender + " and your body type is ";
word_wrap(finalize_B, finalize_S.c_str(), 80);
cout << endl << finalize_S;
if (body == 1)
{
char finalizewhale_B[3000] = {0};
string finalizewhale_S = "fat and blubbery.";
word_wrap(finalizewhale_B, finalizewhale_S.c_str(), 80);
cout << finalizewhale_S << endl;
}
elseif (body == 2)
{
char finalizeburly_B[3000] = {0};
string finalizeburly_S = "burly and strong.";
word_wrap(finalizeburly_B, finalizeburly_S.c_str(), 80);
cout << finalizeburly_S << endl;
}
Using the function inside of if checks to append additional strings breaks the ability to word wrap. Does anyone know if this is easily fixable?
Hi coder777, I tried your method, but it breaks the wordwrapping of finalize_S, and only applies the word wrap to the "fat and blubbery" part.
I think I give up on this word wrap... for such a simple thing it feels like rocket science to a beginner like me and it's way more frustration than it's worth. I'm going to try cire's wordwrap function later, hopefully it'll work the way I want it to, otherwise I give up.
Thanks everyone for all the time you took to help, I really appreciate it.