Sign in to follow this  
jmpeer

[C/C++] Quick Question on I/O

Recommended Posts

jmpeer    100
Hey. I have a quick question. If I'm reading a text file line by line, and it's formatted like this: [string with spaces][1][2][3][4] How can I read those into variables the quickest? I know of fscanf and the %s flag, but once it reads a space, it ignores the rest of the string after it. Using substrings seems redundant and impractical, so I'm asking you guys... *----------------------------------------------------------------------------* EDIT: Text File Example: [Alexander the Great][Apple Pie][15][65][99][10] [Teddy R][This is a flash drive][100][0][85][21184] [E is for Pants][Yummo Pudding!][43][633][2][46] Syntax for Text File Example: [string][string][int][int][int][int] Problem: Each line in the text file is an entry. There are two strings with an undefined number of characters and undefined number of spaces. The characters '[' and ']' separate each variable. Normally I'd use fscanf %s, %s, %d, %d, %d, %d if there were no spaces. But, fscanf stops reading the string after it hits a space. So, for the first entry, instead of having str1="Alexander the Great" and str2="Apple Pie", it would be str1="Alexander" and str2="the". In a sense, I need a function that acts like fscanf, but stops reading the string when it comes across characters I assign, like ',', instead of spaces, newlines, tabs, and EOF, or whatever it stops at. I CAN do this, by reading each line/entry into a string and then breaking it up by searching for the indexes of the '[' and ']' characters, extracting substrings, and converting the numbers from char* to int. But, again, that seems impractical, and I would hope someone thought of this when they were designing C++. [Edited by - jmpeer on March 15, 2010 11:20:33 AM]

Share this post


Link to post
Share on other sites
Buckeye    10747
You might want to try to read in the line to a string and use the functions find_first, find_first_of, find_first_not_of, etc.

Share this post


Link to post
Share on other sites
SiCrane    11839
I'm not entirely clear on the format of your file. Could you post some sample lines and how you expect them to be parsed?

Share this post


Link to post
Share on other sites
Antheus    2409
"Hello World 21 43 726 1321"

Can be read rearranged to:

"1231 627 34 12 dlroW olleH"

Does this help?

This is a very specific solution to a very specific problem, but it doesn't require any substring or even complex search operations, and can be implemented very simply using sscanf, or >>.

Share this post


Link to post
Share on other sites
GregMichael    135
Read the entire file into memory - you should be able to work out the file size which will give you the endpoint (EOF).

Write GetStringToken() and GetIntToken() functions.

Where a string token is defined as:

Starts with '['
Contains characters A-Z, a-z, space/tab etc. possibly digits 0-9, underscore etc.
Ends with ']'

Int token defined as:

Starts with '['
Contains characters 0-9...if negative numbers are required then '-' is also valid, if it's the very first character.
Ends with ']'

For a line to be valid (from your format) there must be 2 string tokens followed by 4 int tokens followed by the end-of-line marker ('\n' or 0x0D 0x0A in binary IIRC).

Share this post


Link to post
Share on other sites
Antheus    2409
There is no fast (better yet, trivial) way to do it.

Read file line by line, mangle those strings.

Quote:
I would hope someone thought of this when they were designing C++.

Hahaha... but no.

C++ is serious business. One needs to use boost::spirit to tackle such problems. Unless it involves much template magic, it is too trivial. A split() function? In standard library? Blasphemy.

There is strtok, but even that isn't best suited for this.

Share this post


Link to post
Share on other sites
jmpeer    100
SOLVED.
Alrighty, I've been reading replies and I realized I forgot about %[ ] when using fscanf. I've surprisingly never used it ever since I first looked into C/C++ a while ago.

Anyway, here's the code. See what it does if you're interested or in for a laugh at how stupid I am:

/*
Text File Read: (archive.txt)
[Alexander the Great][Apple Pie][15][65][99][10]
[Teddy R][This is a flash drive][100][0][85][21184]
[E is for Pants][Yummo Pudding!][43][633][2][46]

Printed In Console:
Alexander the Great Apple Pie 15 65 99 10
Teddy R This is a flash drive 100 0 85 21184
E is for Pants Yummo Pudding! 43 633 2 46
*/

#include <stdio.h>

typedef struct
{
char str1[51], str2[51];
int i1, i2, i3, i4;
}item;

int main()
{

FILE* archive = fopen("archive.txt","r");

item items[3];
int i=0;

//Read File
for(i=0; !feof(archive); i++)
{
fscanf(archive, "[%50[a-z A-Z!/]][%50[a-z A-Z!/]][%d][%d][%d][%d]\n", items[i].str1, items[i].str2,
&items[i].i1, &items[i].i2, &items[i].i3, &items[i].i4);
}

//Print Results
for(i=0; i<3; i++)
{
printf("%s %s %d %d %d %d\n", items[i].str1, items[i].str2, items[i].i1, items[i].i2, items[i].i3, items[i].i4);
}

fclose(archive);
return 0;
}



Peace <3

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this