Strings, getline, strcpy I don't understand

May 27, 2011 at 3:20pm
I've read so many posts etc about this stuff and really don't get it

1
2
3
4
ifstream myfile("do.txt");
std::string part;
std::string line;
getline(myfile, part, "Ignoreme");


I've tried a number of variations on this, but MVC 2010 Express complaints that "getline" doesn't work and other variations on it including istream, std:: produces problems as well.

Then I try to do something like
 
strcpy (part, line);

and it complains again, saying "error: no suitable conversion function from "std::string" to "char" exists", but they're both strings pulled from the file.

I've also read for "getline" from a file you're supposed to write

 
std::getline(ss, part, "ignoreme");

ss being created by "std::strinstream ss(line), and "part" being a string, but MVC complains about this too. I think I've just been overloaded with wrong answers etc and am hoping to UNDERSTAND how to do these things. Goal is to acquire a line of text from a text file and to put it into a string and do stuff to it, such as moving to other strings, etc. But I can't find a thorough explanation (at least that I can understand) on how these functions are actually working, seems like there's always some part that is left out of the explanation.
May 27, 2011 at 3:24pm
http://www.cplusplus.com/reference/string/getline/
I'm almost certain the last parameter should be a character (eg 'c' and not "cat")
Last edited on May 27, 2011 at 3:25pm
May 27, 2011 at 3:28pm
Read the getline page, doesn't clarify how to work with a file. Unless I'm supposed to put the file into a string before doing getline?

Are you saying that with "getline" I cannot have a phrase, but only a single character?
May 27, 2011 at 3:28pm
the last parameter of getline defaults to '\n' and can be left out for most purposes. strcpy works on char* (c strings), not on std::string - for those you can just use = to copy a string. Oh, and if you are already using std::, you should also do that with getline and strcpy - those are in the std namespace as well.
May 27, 2011 at 3:32pm
"Doesn't clarify how to work with a file"
An istream is any kind of input stream, such as cin, an ifstream or fstream object, an istringstream or stringstream object, etc.

And yes, you would not do char c = "Hello";, because a char is one character, not a whole string. You would do char c = 'q'; (note the single quotes)
Last edited on May 27, 2011 at 3:33pm
May 27, 2011 at 3:34pm
Thank you for the string = info. But with my "getline" the purpose of it is to go through a file and find a particular text, then discard it, maintaining that location in the file for the start of the next "getline" IE:

file says:

1
2
1
5
1
2
1
6

and I want it to getline until it reaches the 5, then ignore it, then the next getline would be where I want it to be in the file for other manipulation. Though I'm not working with numbers, I'm actually working with txt files of html code.
May 27, 2011 at 3:37pm
getline() only allows you to read until a certain character, not a certain phrase. You'll have to read in the phrase and see if it is what you want to ignore, or if it is what you want to keep. If you don't know how to do this then you can ask, but otherwise I'm not going to go too far into details.
May 27, 2011 at 3:56pm
When you say "read in the phrase" do you mean using getline to check char for char?, or to do a part.find("ignoreme")!=string::npos? Or is there another command similar to getline that can make it easier to do this?
May 27, 2011 at 4:07pm
Well, what I mean is that you need to develop a special way that you handle reading in the file. EG, you could getline until '<' and then ignore until '>', or however you want to do it. If you could be more specific as to how the HTML you are dealing with needs to be interpreted by your program, we can help you in a more specific fashion.
May 27, 2011 at 4:44pm
Okay, I'm looking for data. its normal HTML code. I want the program to read through the file and find "aqq_190_abc" and discard everything up to and including that phrase. Then I want it to remove the first two chars following the previous quote, then erase the first "</span>" that occurs after the previous quote and chars. Then after "</span>" I want it to erase the rest of the text etc after the "</span>" It should leave me with a char or integer to work with.
May 27, 2011 at 5:13pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ifstream Input ("input.html");
bool found = false;
do
{
  Input.ignore(-1, 'a');
  string Tester = "aqq_190_abc";
  found = true;
  for(unsigned long i = 0; i < Tester.length(); ++i)
  {
    if(Tester[i] != char(Input.get()))
    {
      for(unsigned long j = i; j > 1; --j) //don't read in 'a' next time (infinite loop)
      {
        Input.unget();
      }
      found = false;
      break;
    }
  }
}while(!found);
Input.ignore(2);
//After this point, you want to erase the first </span> following the above, but I'm not sure if you want to keep the data between it? 
May 27, 2011 at 10:44pm
Yeah, I want to keep the leftover data that is before the </span>. But I have a lot to think about with the code you gave me, I don't totally understand all of it, probably take me a day to think it over and incorporate it into my understanding.
May 28, 2011 at 12:32am
That code does the first two things you wanted...it finds and discards that string you wanted out, and the two characters after it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ifstream Input ("input.html"); //the input file stream to read from
bool found = false; //a boolean to tell whether we found that string of yours
do //a do-while loop
{
  Input.ignore(-1, 'a'); //ignore until the first letter of your string
  string Tester = "aqq_190_abc"; //Make a temporary string to compare with
  found = true; //Assume we found it this time
  for(unsigned long i = 0; i < Tester.length(); ++i) //loop through and test the rest of the characters
  {
    if(Tester[i] != char(Input.get())) //if they don't match up with your string,
    {
      for(unsigned long j = i; j > 1; --j) //loop backwards until just before 'a'
      {
        Input.unget(); //go backwards in the stream
      } //this way it can still find aaqq_190...etc when trying to find aqq_190...etc
      found = false; //since this wasn't actually our find, set found to false
      break; //stop looking for a match - we already determined this wasn't it
    }
  }
}while(!found); //loop until we find your string
Input.ignore(2); //skip past those next to characters you don't want 


For more information check this:
http://www.cplusplus.com/reference/iostream/ifstream/

After that code you would probably want to do similar code but for "</span>" instead of "aqq_190_abc", and instead of the Input.ignore(-1, '<') you would do, use this code instead:
1
2
3
4
5
char c;
while(c = char(Input.get()) != '<')
{
  YourDataStringOrSomething += c;
}


As for erasing the rest of the stuff afterwards...you can just close the file and forget that the other stuff was even there:
Input.close();

Then you could convert YourDataStringOrSomething to a number with a stringstream:
1
2
3
istringstream ss (YourDataStringOrSomething);
int EndValue;
ss >> EndValue;


Remember, the C++ reference on this site is a powerful tool if you understand it. Read any parts of it you don't know about or are curious about, and refer to it when in doubt. Eventually, you'll know most of the stuff you normally use by memory, and you will only need the reference for something new.

http://www.cplusplus.com/reference/
Last edited on May 28, 2011 at 12:41am
May 28, 2011 at 1:45pm
Thank you very much for those details. I actually didn't really want to ask for that as its pretty detailed and figured it'd be laborious to explain it to me like you did, but it helps a lot, thank you.

I have been reading up the references but its very hard for me, I've never taken a course in C++ and have tried, over the years to read books about it, but got bored quickly each time (cout << "Hello World" gets old pretty quickly). So earlier this year I started getting into it strong w/o a book and I typically don't understand the terms that are used and have a very hard time understanding the descriptions of the more advanced commands and their variables. Additionally, I have a hard time deciphering variables from commands within some of the references. Such as, I don't get what "ss" stands for in "istringstream" or, as I've seen it "stringstream" and the references aren't worded so that someone with my kind of experience can easily decipher them. (not that I'm against trying to make sense of things, but it gets pretty hard for me). I would like to ask, as I implied, what does "ss" mean? Is it just a variable, or is it a call to a particular sub command of "istringstream" and "stringstream"?

Also, do strings need to be re-identified when they are declared within main () and you go to another, what is it called, a "function"? Such as writing "writefile();" within main () and going to "int writefile();? Or does it travel there. As I understand it, if you declare an "int" or "char" etc in one function, and go to another function, it doesn't carry over, but if you declare it at the beginning of the program, it will work throughout all functions.

One more question; with something such as "string Tester = "aqq_190_abc";" can I also do "string Tester = testerdata.c_str();" so that the testing phrase can be a string variable that I can manipulate?

Thanks again.
May 29, 2011 at 5:52pm
1. 'ss' is just a variable. Functions almost always have parameter lists ()
2. Normally you don't make global variables (variables decalared outside of main), you normally p-ass the variables as parameters to the functions (i.e. MyFunc(MyString, MyInt); )
3. Yes...but not with the .c_str() part. If Tester and testerdata are both std::strings, then you can just do Tester = tesderdata;
Topic archived. No new replies allowed.