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

## Recommended Posts

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 on other sites
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 on other sites
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 on other sites
"Hello World 21 43 726 1321"

"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 on other sites
I made an edit to clarify what I'm looking for.

##### Share on other sites
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 on other sites
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 on other sites
It's not rocket science though...

##### Share on other sites
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 10Teddy R This is a flash drive 100 0 85 21184E 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

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627707
• Total Posts
2978721

• 21
• 14
• 12
• 22
• 35