C: extract string from file

S

Sharon

hi,

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I know how to go to next line but have no idea how to extract string
thank you for answering!


short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}
 
L

lallous

Hello,

Sharon said:
hi,

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I know how to go to next line but have no idea how to extract string
thank you for answering!


short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}
If your read string was: "1 This is the string 2 3 4" you
can parse it using strncpy() as:

char str[100];
strncpy(str, line+10, 35);
str[35] = 0;
 
S

Sharon

lallous said:
Hello,

Sharon said:
hi,

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I know how to go to next line but have no idea how to extract string
thank you for answering!


short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}
If your read string was: "1 This is the string 2 3 4" you
can parse it using strncpy() as:

char str[100];
strncpy(str, line+10, 35);
str[35] = 0;
sorry, I don't understand
how to get the value of "line" ?
e.g. using functions like "fgetc( file)" ??
 
R

Robert W Hand

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I would use fgets to read a line into a character array. Then I would
string copy the section that I wanted into a second character array.
Something like this might work for you:

char* source="1 This is the string 2 3 4";
char destination[26]={0};
strncpy(destination, source+10, 25);
printf("\"%s\"\n", destination);

The output on my system is:

"This is the string "

Note that you need to make sure that the destination array is null
terminated. I did that in the initialization step.
 
M

mirtoto

U¿ytkownik "Sharon said:
lallous said:
Hello,

Sharon said:
hi,

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I know how to go to next line but have no idea how to extract string
thank you for answering!


short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}
If your read string was: "1 This is the string 2 3 4" you
can parse it using strncpy() as:

char str[100];
strncpy(str, line+10, 35);
str[35] = 0;
sorry, I don't understand
how to get the value of "line" ?
e.g. using functions like "fgetc( file)" ??

I think so you didn't keep characters which you read. Your function reading
line of text from file should look like this:

#define MAX_LEN_OF_LINE 256
char line[MAX_LEN_OF_LINE];
int i=0;
memset(line , '\0', sizeof(line));
while (((c=fgetc( file ))!=EOF) && (i<MAX_LEN_OF_LINE-1))
{
if ( c == '\n' ) break;
line[i++]=c;
}

Now you can use strncpy function to extract substring from "line" variable.

Mirek T.
 
M

Malcolm

Sharon said:
I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?
This is rather an awkward line format. If the string can't contain
whitespace you can use the scanf() family of fuctions. Does the string
always start at position 10? Is it always 35 characters long?
I know how to go to next line but have no idea how to extract string
thank you for answering!


short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}
OK this is a start. fgets() will read a line from a file for you. Or if you
like you can roll your own.

void readline(char *str, int maxlen, FILE *file)
{
int c;
while ( ( c = fgetc( file ) ) != EOF )
{
maxlen--;
if(maxlen <= 0)
break;
if ( c == '\n' )
break;
*str++ = (char) c;
}
/* add terminating NUL */
*str = 0;
}

(You might want to think about handling error conditions).

Once you've got your line into a string, you can write this function

/*
extract a substring.
in - input string.
out - pointer to output buffer.
start - start position
len - length of substring.
*/
void extract(const char *in, char *out, int start, int len)
{
}
 
J

Joe Wright

Sharon said:
hi,

I want to extract a string from a file,
if the file is like this:
1 This is the string 2 3 4

how could I extract the string, starting from the 10th position (i.e. "T")
and extract 35 characters (including "T") from a file and then go to next
line?

I know how to go to next line but have no idea how to extract string
thank you for answering!

short c;

/* code for extract the string from file */

while ( ( c = fgetc( file ) ) != EOF )
{
if ( c == '\n' )
break;
}

This will sound like nit-picking but text files don't have strings in
them. Really. Strings are memory things. Lines are file things. Assuming
you have a file whose first line looks like your example, do something
like this..

char line[256]; /* some too-long number */
.... open the file, etc.
fgets(line, sizeof line, file);

This will read the line from the file and make a string out of it in
line[].

"1 This is the string 2 3 4\n"
012345678901234567890123456789012345678901
1 2 3 4
This is a string because fgets has placed a '\0' in line[41] just past
the '\n'. Note that 'T' is at line[10] but is the eleventh character,
not the tenth. Note also that there are not 35 characters on the line
after the 'T'.
 
P

Paul Hsieh

lallous said:
If your read string was: "1 This is the string 2 3 4" you
can parse it using strncpy() as:

char str[100];
strncpy(str, line+10, 35);
str[35] = 0;
sorry, I don't understand
how to get the value of "line" ?
e.g. using functions like "fgetc( file)" ??

The common suggestion which is equivalent to the loop around fgetc() ideas
posted here is to use fgets() to get each line. For technical reasons one
might use a getInput()-style function instead, which you can find here:
http://www.pobox.com/~qed/userInput.html . So using a getInput function its
something like:

FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char * line;

while (!feof (fp)) {
line = NULL;
int len = fgetstralloc (&line, fp);
if (len > 10) {
char substr[36];
strncpy (substr, line + 10, 35);
substr[35] = '\0';

printf ("<<%s>>\n", substr);
}
free (line);
}
fclose (fp);
}

Otherwise if you just want to use fgets ... either life gets really really
difficult or you can implement a "truncated line" solution and hope for the
best:

#define MAX_LINE_SIZE (192)
FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char line [MAX_LINE_SIZE];
while (!feof (fp)) {
/* This will just screw up if you have a line of > 192
characters and fixing it is annoying. Also this
comment will be out of data when you change
MAX_LINE_SIZE. */
fgets (line, MAX_LINE_SIZE, fp);
if (strlen (line) > 10) {
char substr[36];
strncpy (substr, line + 10, 35);
substr[35] = '\0';
printf ("<<%s>>\n", substr);
}
}
fclose (fp);
}

Of course, if you wanted to do a completely incremental approach (whose ideas
are not really reusable as you try to solve more complex problems) then you
could just do this:

FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char str[36];
int s = 0;
int c;

while (EOF != (c = fgetc (fp)) {
if (c == '\n') {
str[s-10] = '\0';
printf ("<<%s>>\n", str);
s = 0;
}
if (s >= 10) {
if (s < 35 + 10) str[s-10] = c;
else if (s == 35 + 10) {
str[35] = '\0';
printf ("<<%s>>\n", str);
s = 0;
}
}
s++;
}
fclose (fp);
}

But this solution is a little bit complicated and may need some debugging to
make sure it works properly. Documenting it might be a little difficult as
well.

Another expressive way of doing this is to use a string library which is likely
to contain useful facilities for this purpose. One example is to use "the
better string library" (http://bstring.sf.net):

FILE * fp = fopen ("name_of_file.txt", "rb");
bstring b, s;

if (fp) {
while (!feof (fp)) {
s = bmidstr (b = bgets ((bNgetc) fgetc, fp, '\n'), 10, 35);
printf ("<<%s>>\n", s->data);
bdestroy (b);
bdestroy (s);
}
fclose (fp);
}

which is probably the easiest solution.
 
D

Dave Thompson

On Tue, 23 Dec 2003 03:11:04 GMT, (e-mail address removed) (Paul Hsieh) wrote:
The common suggestion which is equivalent to the loop around fgetc() ideas
posted here is to use fgets() to get each line. For technical reasons one
might use a getInput()-style function instead, which you can find here:
http://www.pobox.com/~qed/userInput.html . So using a getInput function its
something like:

FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char * line;

while (!feof (fp)) {
line = NULL;
int len = fgetstralloc (&line, fp);
if (len > 10) {

I haven't looked at your version of getline, but I hope here it is
returning a value <= 10, probably < 0 (or 1?), for EOF or I/O error.
If an input error occurs, which is admittedly unlikelyl if that name
accesses a disc file as is likely, this loop will run forever;
fgetstralloc() will keep failing, while !feof(fp) remains true.
You should test ferror(fp) also, and might as well put the tests at
the bottom with do ... while() instead of while() ....
char substr[36];
strncpy (substr, line + 10, 35);
substr[35] = '\0';

printf ("<<%s>>\n", substr);

Aside: if the *only* thing you want to do with a substring is *printf
it, you can just use %.35s with line+10. The OP didn't say that is
what she wanted, although 'extract' *might* mean that.
}
free (line);
}

Curiosity: why is len, whose value is only meaningful per line, local
to the loop body, while line, whose value you make meaningful only per
line although I'm guessing it *could* be otherwise, not?
fclose (fp);
}

Otherwise if you just want to use fgets ... either life gets really really
difficult or you can implement a "truncated line" solution and hope for the
best:

#define MAX_LINE_SIZE (192)
FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char line [MAX_LINE_SIZE];
while (!feof (fp)) {
/* This will just screw up if you have a line of > 192
characters and fixing it is annoying. Also this
comment will be out of data when you change
MAX_LINE_SIZE. */
fgets (line, MAX_LINE_SIZE, fp);
if (strlen (line) > 10) {

The contents of line are undefined if fgets() fails due to I/O error;
in theory this could crash, although in practice it will probably just
be garbage or the last line. Infinitely, as for the one above.
char substr[36];
strncpy (substr, line + 10, 35);
substr[35] = '\0';
printf ("<<%s>>\n", substr);
}
}
fclose (fp);
}

Of course, if you wanted to do a completely incremental approach (whose ideas
are not really reusable as you try to solve more complex problems) then you
could just do this:

FILE * fp = fopen ("name_of_file.txt", "rb");
if (fp) {
char str[36];
int s = 0;
int c;

while (EOF != (c = fgetc (fp)) {
if (c == '\n') {
str[s-10] = '\0';
printf ("<<%s>>\n", str);
s = 0;
}
if (s >= 10) {
if (s < 35 + 10) str[s-10] = c;
else if (s == 35 + 10) {
str[35] = '\0';
printf ("<<%s>>\n", str);
s = 0;
}
}
s++;
}
fclose (fp);
}
Fails catastrophically on an input line less than 10 characters, or
between 45 and (I'm pretty sure) 53 and so on; off-by-one in lines
after the first; produces multiple pieces from lines longer than 53
characters, which I don't think was desired; produces no output at all
from a last (or only) line unterminated by \n on implementations which
support that.
But this solution is a little bit complicated and may need some debugging to
make sure it works properly. Documenting it might be a little difficult as
well.
Uh, er, yeah :)
Another expressive way of doing this is to use a string library which is likely
to contain useful facilities for this purpose. One example is to use "the
better string library" (http://bstring.sf.net):

FILE * fp = fopen ("name_of_file.txt", "rb");
bstring b, s;

if (fp) {
while (!feof (fp)) {
s = bmidstr (b = bgets ((bNgetc) fgetc, fp, '\n'), 10, 35);

Again assuming your routines are safe for error or EOF, and again
continues looping forever on error, unless your bgets() exit's or
longjmp's. (And assuming you're not on my rare TNS1-equivalent where
FILE* is different from void* said:
printf ("<<%s>>\n", s->data);
bdestroy (b);
bdestroy (s);
}
fclose (fp);
}

which is probably the easiest solution.

- David.Thompson1 at worldnet.att.net
 
P

Paul Hsieh

Dave Thompson said:
On Tue, 23 Dec 2003 03:11:04 GMT, (e-mail address removed) (Paul Hsieh) wrote:


I haven't looked at your version of getline, but I hope here it is
returning a value <= 10, probably < 0 (or 1?), for EOF or I/O error.

Its written on top of fgetc(), so an error or EOF will be detected and
unified to mean the same thing causing the input line to terminate at
that point.
If an input error occurs, which is admittedly unlikelyl if that name
accesses a disc file as is likely, this loop will run forever;
fgetstralloc() will keep failing, while !feof(fp) remains true.
You should test ferror(fp) also,

Fine, so replace my feof() with (feof(fp) || ferror(fp)). Besides a
mindless bug for a mindless solution, you quoted my entire longish
post just to point this out three more times -- go look up the word
"constructive" as it relates to the phrase "constructive criticism"
(keeping in mind that the OP was trying the learn something, other
than the existence of hardware that became obsolete long before the
existence of USENET.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top