How to create a newline without breaking the token?

60 Views Asked by At

So I am trying to write to a file I/O in C++ where the user wants to translate a different language, an example would be morse code to english. I using the function morseToEnglish() and passing it in as a token for my output file. The issue I am having with this is that I am getting the correct output, but I am missing a newline somewhere.

Here is what I have so far:

        char morsing[256]; //reading line by line
        if (inputfile.is_open())
        { 
            while (inputfile.getline(morsing, 256)) // reading character by character
            {                                    
                token = strtok(morsing, "|"); //break each word into token
                cout << "Read the input file: " << "morsingMC.mc" << endl;
                while (token != NULL)
                {
                    **outputfile << morseToEnglish(morsing); **
                    token = strtok(NULL, "|");

                } 
            } 
        }

If I am doing

outputfile << morseToEnglish(morsing); 

this will be the output:

123 456 789123 456 789123 456 789123 456 789123 456 789

instead of:

123 456 789
123 456 789
123 456 789
123 456 789
123 456 789

I have also tried using the endl and "\n" with my outputfile but this will output each word into token instead. This is a minor change but how can I modify my newline so that my output will go to a newline without breaking the token?

Edit: morseToEnglish() is a function that converts morse code into English which is in the header file and inputfile/outputfile are ifstream/ofstream respectively

1

There are 1 best solutions below

0
Jerry Coffin On

Okay, let's start with a really simple bit of advice: when you're writing C++, forget that you ever even heard of strtok. Just don't use it--ever.

While you're at it, it's probably just as well to forget about the existence of std::istream::getline as well. If you want to read a line of data, your first choice should usually be std::getline instead. That works with an std::string--which should usually be your first choice for how to store/represent/manipulate strings.

Yes, there are exceptions to all of that, but they're reasonable starting points until/unless you have some specific reason to do otherwise.

Getting to the question, I surmise you have some input like:

<token>|<token>|<token>|<token>\n

So, for example, if a line of input contained the classic "SOS", it would be something like:

...|---|...

Seem at least sort of close to reality so far?

I'm also guessing that what you're hoping to achieve is read in a line, translate each token on that line into English, print out the tokens, print a new-line, and then proceed to the next, and repeat until the end of the file.

Assuming that's the case, I'd write the code something like this:

std::string line;

while (std::getline(inputfile, line)) {
    process(line);
}

Then process will process one line of input, something like this:

void process(std::string const &line) {
    std::istringstream buffer(line);

    std::string token;
    while (std::getline(buffer, token, '|')) {
        outputfile << morsetoenglish(token);
    }
    outputfile << '\n';
}

That is guessing about what you want, but if I'm reading things right, it seems to fit at least reasonably closely.