0

I am trying to read from a file, but I keep getting control characters at the end of my string. I use the for loop to check for them and it prints out that there is one for every word, but only if I add the + 1 to temp.size(). I don't want to read them from the file. I am really confused why this is happening.

int main(){
    ifstream inFile;
    vector<string> vect;
    string temp = "";

    //Reading from a file line by line
    inFile.open("words.txt");
    if (inFile.is_open())
    {
        while (!inFile.eof())
        {
            getline(inFile, temp);
            vect.push_back(temp);
        }
    }
    inFile.close();

    //checking through each character of the string to see if it has a control character.
    for (int i = 0; i < vect.size(); i++)
    {
        temp = vect[i];
        for (int j = 0; j < temp.size() + 1; j++)
        {
            if (iscntrl(temp[j]))
            {
                cout << temp << " There is a space\n";
            }
        }
    }

    return 0;
}

.txt file image

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
natedawg
  • 21
  • 2
  • why are you not printing the code nor the position in the line of the control char ? – bruno Aug 24 '20 at 19:52
  • If you are on Windows, it may be that the CRLF line endings are reading the CR as part of the line rather than as part of the CRLF end-of-line marker. Opening such files in text mode will treat the CRLF pair of characters as the end-of-line marker. Or you can strip it off manually. – Eljay Aug 24 '20 at 21:04
  • `getline()` handles bare-LF and CRLF line breaks on Windows. – Remy Lebeau Aug 24 '20 at 21:23

1 Answers1

7

The root cause of your issue is that your for loop is accessing the temp string's null-terminator (technically, in a way that is undefined behavior prior to C++11). iscntrl() considers character '\0' (0x00) to be a control character. You need to change this:

for (int j = 0; j < temp.size() + 1; j++)

to this:

for (size_t j = 0; j < temp.size(); j++)

The null-terminator is not part of a std::string's size/payload, but it is present for compatibility so that std::string can be used with C-based APIs.


Also, unrelated to that problem, your while loop is broken. See Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?. You need to replace this:

while (!inFile.eof())
{
    getline(inFile, temp);
    vect.push_back(temp);
}

with this:

while (getline(inFile, temp))
{
    vect.push_back(temp);
}
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620