Hi,
I'm basically trying to create captions that will go under an image in my project.. the problem is that if the caption line is too long, it will get chopped off... so I'm trying to write a function that will re-chop a string with endl's according to the width of the images..

But when I run this, I'm getting runtime errors, saying something about bad memory allocation.. I can't see what the problem is, and I can't really think of an easier way to do it..

Any help is appreciated!

// Basically the function reads text from a file (file) and updates a string (captionText) by reference, using captionWidth as a parameter.. captionLines is also updated for other reasons..

#include <fstream>
#include <string>
#include <iostream>

void get_caption (std::fstream& file,
                  std::string& captionText,
                  unsigned captionWidth,
                  unsigned& captionLines)
{
    std::string eachLine;
    while (!file.eof())
    {
        std::getline(std::cin,eachLine);
        captionText += eachLine;
    }
    unsigned charsPerLine = (12/100) * captionWidth; // 12 chars fit under 100 pixels of image
    for (int i=charsPerLine; i<captionText.size(); i+=charsPerLine)
    {
        if (i >= captionText.size())
            return;
        while (captionText.at(i) != ' ' && captionText.at(i) != '\n')
            i--;
        captionText.at(i) = '\n';
        captionLines++;
    }
    return;
}

Line 15: Reading from cin, read from "file".
Line 18: This would always set charsPerLine to 0. (12/100) would evaluate to 0. Make it (12.0/100.0)
Line 23-24: Not clear what are you trying to do. Remember getline() remove teh '\n' char. So you won't find that in captionText. This would crash also. Assuming that charsPerLine is 5 AND there is no space in first 5 chars of captionText. This loop will keep doing --i and would make i negative, which will result in crash. (to protect against the crash you can add one more condition i >= 0 as the first condition in the while, but I'm not sure what are you doing so can't say if it's correct to do)
Line 25: This would replace ith char, not insert '\n' as (i+1)th char.

Assuming that your file contains one caption per line; and you want to read each caption from the file, chop off the unwanted chars; and store these captions in a single std::string variable separated by '\n' you can do it like this:

while( ! EOF )
{
           read eachLine from file
                 if( eachLine.size() > allowed_caption_size )
                                output_string += chopOff( eachLine ) + '\n' ;
                 else
                                output_string += eachLine + '\n' ;
}
//PS: remove extra '\n' at the end if required

Finally: I would suggest that you use vector instead of a single string containing all captions separated by '\n'. This seems to be a perfect usecase for vector. If you use it your function signature would look like this:

void get_caption (fstream& file,
                  vector<string>& captionTextsVec,
                  unsigned captionWidth)
//PS: captionLines not needed as captionTextsVec.size() would give you that

Thanks for your help man,

..the getline(cin,..) bit was a typo while I was posting, it actually didn't work regardless of that..

The problem was, as you pointed out, that I was using integer division..
In any case I changed the function completely, and it seems to work now. Vectors wouldn't work because I'm passing captionText into a function that takes a string as a parameter..

Lines 23/24 I was basically saying "if eachLine exceeds allowed width, then (starting at that width and working down) find the nearest white space.. then chop the head of the string off and leave on current line.. then repeat procedure on tail of string until it's within allowed limits"..
(The logic here is that I don't chop words in half, but look for a gap between them so I can chop the sentence without chopping words)

Line 25 I was purposely replacing the whitespace char with a newline char.. the idea being that if I have a sentence like "this is a typical lymphocyte", and max chars is 25 or something, then I end up with:
"this is a typical"
"lymphocyte"
where the space is replaced by a newline char..

But as I said, it seems to work fine now.. I can post you a snippet if you want.. it's probably not the tersest algorithm..

thanks again for your time

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.