4

I have a text file with lines of text that have a string another string followed by up to 4 integers, ex:

clear "clear water.png" 5 7
wet "wet water.png" 9 5 33 17
soft "soft rain falling.png" 

The only way I see it is:

read until space is found

set string to wet

read until double quote

read until second double quote

set second string to wet water.png

while not end of line

read until space

put string through string stream

push resulting integer into vector of int

Is there a better way to do this?

Thanks

jmasterx
  • 52,639
  • 96
  • 311
  • 557

4 Answers4

5

This is the sort of task for which scanf and company truly shine.

char first_string[33], second_string[129];

sscanf(input_string, 
    "%32s%*[^\"]%*c%128[^\"]%*c %d %d %d %d", 
    first_string, 
    second_string, 
    &first_int, 
    &second_int,
    &third_int,
    &fourth_int);

You probably want to do that in an if statement so you can test the return value, to tell you how many of those fields converted (e.g., so you know how many integers you read at the end).

Edit: perhaps some explanation would be helpful. Let's dissect that:

%32s reads a string to the first white-space (or 32 characters, whichever comes first).
%*[^\"] ignores input up to the first ".
%*c ignores one more byte of input (the quote itself)
%128[^\"] reads the string in the quote (i.e., up to the next quote character).
%*c Ignores the closing quote %d Reads an int (which we've done four times).

The space before each %d is really unnecessary -- it'll skip whitespace, but without the space, %d will skip leading whitespace anyway. I've included them purely to make it a little more readable.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I find that to be a great answer! – Andro Dec 02 '11 at 23:18
  • I *had* to upvote this, although I don't have a high opinion of `scanf` and it's not idiomatic C++. – Jon Dec 02 '11 at 23:20
  • @ybungalobill: what do you think is nonstandard about it? If you're thinking of the `%[^\"]`, you're mistaken -- that's a scanset conversion which is part of standard C. It isn't new either -- although not in K&R1, it's been in the standard from the beginning because by then it was already widespread. – Jerry Coffin Dec 02 '11 at 23:21
  • @JerryCoffin: Hmm, don't have the C89 standard, but as per C99 you're right. Didn't know this. Thanks! – Yakov Galka Dec 02 '11 at 23:26
1

Ugly, with no error-checking, but no dependencies on any non-standard libraries:

string s;
while(getline(fin, s))
{
    string word, quoted_string;
    vector<int> vec;

    istringstream line(s);
    line >> word;
    line.ignore(numeric_limits<streamsize>::max(), '"');
    getline(line, quoted_string, '"');
    int n;
    while(line >> n) vec.push_back(n);

    // do something with word, quoted_string and vec...
}
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
0

Depending on the restrictions of the input strings you could trying splitting on double-quote then splitting on space.

SundayMonday
  • 19,147
  • 29
  • 100
  • 154
0

Yes

Use getline to read one line at a time. Parse the lines using a regular expression library.

Community
  • 1
  • 1
kevin cline
  • 2,608
  • 2
  • 25
  • 38