Home > Software engineering >  C substring not giving me the correct result
C substring not giving me the correct result

Time:06-11

I have the following code:

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

using namespace std;

int main()
{
    fstream file;
    string s;
    //file contains the following
    //id="123456789"
    //Note: There is no spaces at the end
    file.open("test.txt", ios::in);
    getline(file, s);
    s = s.substr(s.find("\"") 1, s.length()-1);
    cout << s << endl;
    return 0;
}

The results print:

123456789"

Why is there a quote at the end? A weird thing is that when I change s.length()-1 to s.length()-5, the code work how I wanted it to. What is the problem here?

CodePudding user response:

The 2nd parameter of string::substr() is a count, not an index, like you are treating it.

In your example, s.length()=14, so you are asking for 14-1=13 characters starting at the index 1 past the 1st " character (3 1=4), but there are only 10 characters remaining from that position onward. That is why the 2nd " character is being included in the substring.

Use string::find() again to find the index of the 2nd " character, and then subtract the two indexes to get the length between them, eg:

auto start = s.find('\"')   1;
auto stop = s.find('\"', start);
s = s.substr(start, stop-start); 

start will be the index 1 past the 1st " character (3 1=4), and stop will be the index of the 2nd " character (13). Thus, the length you get is 13-4=9 characters.


Another way to handle this would be to put the string into an istringstream and then use the std::quoted I/O manipulator to extract the substring between the " characters, eg:

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
    ifstream file("test.txt");
    string s;
    getline(file, s);
    istringstream iss(s);
    iss.ignore(3);
    iss >> quoted(s);
    cout << s << endl;
    return 0;
}

CodePudding user response:

The expression s.length()-1 yields the length of the whole string except one character.

You should write for example

auto n = s.find("\"");

s = s.substr( n 1, s.length() - n - 2 );

Or you could write the following way

    auto n = s.find( '"' );
    s = s.substr( n   1, s.rfind( '"' ) - n - 1 );
  • Related