0

Ok, I know my title is very unclear but I think part of the problem is that I don't know how to explain it clearly enough for Google to be useful.

Basically I have two functions:

    SentenceData parseSingleSentence(std::string inputString)
    {
        SentenceData actualSentenceData;

        actualSentenceData.transmitter = inputString.substr(1, 2);
        actualSentenceData.format = inputString.substr(3, 3);

        // Data fields run from first ',' (index 7) and the last 3 characters can be disregarded
        std::stringstream ss(inputString.substr(7, inputString.length()-10));
        std::string newDataField;
        while (!ss.eof()) {
            getline(ss, newDataField, ',');
            actualSentenceData.dataFields.push_back(newDataField);
        }

        return actualSentenceData;
    }

    bool hasCorrectNumberOfFields(SentenceData sentenceData)
    {
        std::map<std::string, int>::iterator iterator = supportedFormats.begin();
        while (iterator != supportedFormats.end())
        {
            if (sentenceData.format == iterator->first && int(sentenceData.dataFields.size()) == iterator->second) return true;
            ++iterator;
        }

        return false;
    }

In my main(), I would like to run:

    parseSingleSentence(inputString);
    if (!hasCorrectNumberOfFields(actualSentenceData)) continue;

However, there is a clear problem - the compiler doesn't recognise that actualSentenceData will be returned after parseSingleSentence() is called.

The error is: 376:43: Use of undeclared identifier 'actualSentenceData'

I was originally expecting the compiler to recognise that the appropriate variable would be returned by the first function. When it threw up the error I quickly realised the problem but don't understand what the solution could be.

Is there a fix for this? I've spent several hours trying to find out what I've missed and don't know where to go from here.

I've searched on Google and Stack Overflow. Plus looked through several C++ websites, watched some tutorials, and my lectures from university.

  • You never receive the value from `parseSingleSentence(inputString);` to store it in a variable. – πάντα ῥεῖ Feb 28 '23 at 18:58
  • On a side note: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/) Inside of `parseSingleSentence()`, the loop `while (!ss.eof()) { getline(ss, newDataField, ','); ... }` should be `while (getline(ss, newDataField, ',')) { ... }` instead. – Remy Lebeau Feb 28 '23 at 20:53

2 Answers2

2

You need to capture the return value in another variable (which you can call anything you like, here I called it sd).

SentenceData sd = parseSingleSentence(inputString);
if (!hasCorrectNumberOfFields(sd)) continue;

Local variables only exist in the function they are declared in, return doesn't change that. What is returned from a function is a value not a variable. If you want to save that value you need another variable.

john
  • 85,011
  • 4
  • 57
  • 81
2

I guess u mean smth like that:

SentenceData data = parseSingleSentence(inputString);
if (!hasCorrectNumberOfFields(data)) { 
  continue;
}

Additionally:

  1. Its considered good to reduce the variable scope, so if u use modern C++ standards, u can use the following optionally:
if (auto data = parseSingleSentence(inputString); !hasCorrectNumberOfFields(data)) {
  continue;
}
  1. The parameter in hasCorrectNumberOfFields is taken by value, u would better to use const& or pass it by value and use std::move(data) when calling it, if SentenceData has a move constructor.

  2. U'd better replacing while loop with range-based-for:

bool hasCorrectNumberOfFields(SentenceData sentenceData) {
  for (const auto& [format, fields]: supportedFormats) {
    if (sentenceData.format == format && 
        (int)sentenceData.dataFields.size() == fields) 
    { 
       return true;
    }
  }
  return false;
}
excommunicado
  • 287
  • 1
  • 10