473,769 Members | 7,388 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

fscanf and linked list problem

Kay
1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon and
save it in three different variables ?

2) If I enter a number, can I use to call a particular node ?
eg enter a number: 3
calling node of number 3
is it possible ?

Nov 14 '05 #1
7 2828
Kay wrote:
1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon and
save it in three different variables ?
Each line can be parsed with (your data types may vary):

fscanf(fp, "%s; %i; %c\n", &var1, &var2, &var3);

2) If I enter a number, can I use to call a particular node ?
eg enter a number: 3
calling node of number 3
is it possible ?


I don't fully understand the question. Do you have a linked list and
want to find the n-th node? Start at the root node and do something like
node = node->next; n times.

--
Tiago
Nov 14 '05 #2


Kay wrote:
1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon and
save it in three different variables ?

2) If I enter a number, can I use to call a particular node ?
eg enter a number: 3
calling node of number 3
is it possible ?


You could try reading a line of text from the file with function
fgets. Then use function sscanf to parse the line. The specifier
%s can be used if the name has no spaces in it. Otherwise you can
use the scanset, []. If you want the number to be type int use
%d for the specifier, or %u if unsigned. Then for the last use %c.

For an example look at function AddBIO_ARR in the code below.

#include <stdio.h>
#include <stdlib.h>

#define LINE_MAX 80

typedef struct BIO
{
char name[64];
unsigned age;
char paylocation;
} BIO;

typedef struct BIO_ARR
{
BIO *bio;
unsigned cnt;
}BIO_ARR;

int AddBIO_ARR(BIO_ ARR *p, const char *s);
void PrintBIO_ARR( BIO_ARR *p);
void FreeBIO_ARR( BIO_ARR *p);

int main(void)
{
char fline[LINE_MAX];
struct BIO_ARR Prez = {NULL,0}; /* Initializes with no Bio Info */
FILE *fp;

if((fp = fopen("test.txt ","r")) == NULL)
{
puts("Unable to open the file");
exit(EXIT_FAILU RE);
}
while(NULL != fgets(fline,siz eof fline,fp))
AddBIO_ARR(&Pre z,fline);
fclose(fp);
PrintBIO_ARR(&P rez);
FreeBIO_ARR(&Pr ez);
return 0;
}

int AddBIO_ARR(BIO_ ARR *p, const char *s)
{
BIO *tmp;

if((tmp = realloc(p->bio,(sizeof *p->bio)*(p->cnt+1))) == NULL)
return 0;
p->bio = tmp;
if(3 != sscanf(s,"%63[^;]; %u; %c",p->bio[p->cnt].name,
&p->bio[p->cnt].age, &p->bio[p->cnt].paylocation))
return 0;
p->cnt++;
return 1;
}

void PrintBIO_ARR( BIO_ARR *p)
{
unsigned i;

for(i = 0; i < p->cnt;i++)
printf("Name: %s\n Age: %u\nPLoc: %c\n\n",
p->bio[i].name, p->bio[i].age,
p->bio[i].paylocation);
return;
}

void FreeBIO_ARR( BIO_ARR *p)
{
free(p->bio);
p->bio = NULL;
p->cnt = 0;
return;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #3
Kay
can it be done by char * name; ?

Al Bowers wrote:


Kay wrote:
1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon and
save it in three different variables ?

2) If I enter a number, can I use to call a particular node ?
eg enter a number: 3
calling node of number 3
is it possible ?


You could try reading a line of text from the file with function
fgets. Then use function sscanf to parse the line. The specifier
%s can be used if the name has no spaces in it. Otherwise you can
use the scanset, []. If you want the number to be type int use
%d for the specifier, or %u if unsigned. Then for the last use %c.

For an example look at function AddBIO_ARR in the code below.

#include <stdio.h>
#include <stdlib.h>

#define LINE_MAX 80

typedef struct BIO
{
char name[64];
unsigned age;
char paylocation;
} BIO;

typedef struct BIO_ARR
{
BIO *bio;
unsigned cnt;
}BIO_ARR;

int AddBIO_ARR(BIO_ ARR *p, const char *s);
void PrintBIO_ARR( BIO_ARR *p);
void FreeBIO_ARR( BIO_ARR *p);

int main(void)
{
char fline[LINE_MAX];
struct BIO_ARR Prez = {NULL,0}; /* Initializes with no Bio Info */
FILE *fp;

if((fp = fopen("test.txt ","r")) == NULL)
{
puts("Unable to open the file");
exit(EXIT_FAILU RE);
}
while(NULL != fgets(fline,siz eof fline,fp))
AddBIO_ARR(&Pre z,fline);
fclose(fp);
PrintBIO_ARR(&P rez);
FreeBIO_ARR(&Pr ez);
return 0;
}

int AddBIO_ARR(BIO_ ARR *p, const char *s)
{
BIO *tmp;

if((tmp = realloc(p->bio,(sizeof *p->bio)*(p->cnt+1))) == NULL)
return 0;
p->bio = tmp;
if(3 != sscanf(s,"%63[^;]; %u; %c",p->bio[p->cnt].name,
&p->bio[p->cnt].age, &p->bio[p->cnt].paylocation))
return 0;
p->cnt++;
return 1;
}

void PrintBIO_ARR( BIO_ARR *p)
{
unsigned i;

for(i = 0; i < p->cnt;i++)
printf("Name: %s\n Age: %u\nPLoc: %c\n\n",
p->bio[i].name, p->bio[i].age,
p->bio[i].paylocation);
return;
}

void FreeBIO_ARR( BIO_ARR *p)
{
free(p->bio);
p->bio = NULL;
p->cnt = 0;
return;
}


Nov 14 '05 #4
>Kay wrote:
1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon and
save it in three different variables ?

( http://www.thecoolkids.org/articles/...onlinelang.php )

In article <news:41******* *************** @news.telepac.p t>
Tiago Quelhas <do*****@netcab o.pt> wrote:Each line can be parsed with (your data types may vary):

fscanf(fp, "%s; %i; %c\n", &var1, &var2, &var3);


No, %s is the wrong format; and "&var1" is almost certainly wrong
as well. %i is legal but may or may not be what is desired.
Lastly, the final newline in the scanf directive does not mean what
I suspect you think it means. :-)

The "%s" directive tells the scanf family of functions to:
(a) read and consume any leading whitespace, including no
whitespace, then
(b) read and convert at least one character, and as many
characters as possible until the next whitespace. If
assignment is not suppressed, these will be stored through
the supplied pointer, writing to *&var, then *((&var)+1),
then *(&var + 2), and so on; after the last character
written, scanf will add the string-terminator marker '\0'.

If "var1" has type "array N of char", the value you want to supply
to the scanf family is the address of the *first element* of var,
not the address of "var" as a whole. Due to type conversions inside
the call, &var is fairly likely to work on most machines, despite
having undefined behavior in the C standard. More importantly,
though, if "var1" has type "array 100 of char" for instance:

char var1[100];

then even if you fix the call to read:

ret = fscanf(fp, "%s; %i; %c\n", &var1[0], &var2, &var3);

the input line "John; 23; a" will write {'J', 'o', 'h', 'n', ';'}
in sequence to var1[0] through var1[4], and set var1[5] to '\0'.
The OP asked to have var1[0] through var1[3] set to "John", without
the semicolon, so var1[4] should hold the '\0'.

(Of course, without a field-width, this fscanf() call is the next
Microsoft security hole waiting to be exploited, as well.)

Now, we can fix this by using scanf's %[ directive to scan for
"characters not including semicolon". Since %[ does *not* skip
leading whitespace, we must decide whether to do so ourselves.
If we choose to skip leading whitespace, and use a fieldwidth
that is correct for "char var1[100]", we could write:

ret = fscanf(fp, " %99[^;]; %i; %c\n", var1, &var2, &var3);

This solves the problem of converting the semicolon, but perhaps
adds a new one: malformed input lines that contain *no* semicolon
will be scanned, newline and all, into var1 until var1 fills up.
For instance, if the text in the input stream at the point of the
call begins with:

" hello there\n\tthis is not proper, is it?\nBob;"

then the " " directive will skip the two initial blanks, but the
subsequent %[ directive will read and convert the next two entire
lines plus the word "Bob" off the third line.

Can this be fixed (assuming it is a problem)? Certainly: just
add newline to the characters excluded from the scanset, giving
" %[^;\n]". But as you can see, things are getting complicated
already.

A well-behaved application will, in my opinion, handle malformed
input files, and if possible, give a hint about fixing such files.
One way to do this is to deliver a message to stderr giving the
input file name and line number. How can you keep track of the
line number? You simply have to take some particular action every
time you cross a newline. The scanf family's whitespace-eating
directives, however, cause a problem: newlines *are* "whitespace ",
and that leading " " in " %[..." will happily scan right over
dozens or hundreds of them, without alerting you. We could fix
that by removing the leading blank, of course, and demanding that
names like "John" and "Mary" appear left-aligned. But what about
the rest of the whitespace directives in the format? There are
four more in "; %i; %c\n", even if two of them are hard to see.
Where are they? Well, the two blanks are obviously whitespace
directives. There is also one hidden inside "%i": %i, %d, %f,
and indeed most of the %-related directives all include one. (The
two exceptions are %[ and %c.) Finally, the newline at the end
of the format is also a whitespace directive. To the scanf family,
there is NO DIFFERENCE AT ALL between " ", "\t", "\n", "\b", and
so on! (In directives, that is.)

Call all this also be fixed? Most of it can, at the expense of
complicating the code enormously:

ret = fscanf("%99[^;\n];%c%i;%c%c%c", var1, &blank1,
&var2, &blank2, &var3, &newline1);
/* now inspect "ret", and if *it* seems OK, then check up on
blank1, blank2, and newline1 to make sure they are the
expected two blanks and a newline */

The "%i" directive is still troublesome. Also, note that %i
conversions are done as if via strtol() with 0 as a base, so that
numeric fields that begin with 0 or 0x are treated as octal or
hexadecimal, as in C. This is often not what one wants with
user input files (although sometimes it is).

There is a much better way to do this job, and that is to read
a complete input line with fgets() or some substitute (such as
CBFalconer's ggets()), then pick it apart, perhaps even with
sscanf(). Each time you read one complete input line, you can
be sure you have read one complete input line -- no more, and
no less. That makes it much easier to print error messages like:

input.file, line 47: wrong format -- I can't understand the
text "this line has no semicolons, oops!"

with something like:

fprintf(stderr, "%s, line %d: wrong format -- I can't "
"understand the text \"%s\"\n", filename, linenumber, inputline);

(note that this assumes the terminating newline has been stripped
from the input line).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #5
Kay wrote:

1) If i want to read data from a txt file,
eg John; 23; a
Mary; 16; i
How can I read the above data stopping reading b4 each semi-colon
and save it in three different variables ?


You will need either the value 180 or the text string "b4" in the
file. When you have arranged that I suggest using the getc()
function.

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 14 '05 #6
Chris Torek wrote:
[a bunch of ad-hoc parsing with scanf]


Alternatively, use a lexer generator such as GNU flex to parse such
files in the desired manner, detect malformed input and report it
correctly, and all such other nice stuff with a smaller description and
less chance of error. Your program will run faster too. You can then use
more specific conversion functions like atof on the individual tokens.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.
Nov 14 '05 #7
fb


Derrick Coetzee wrote:
Chris Torek wrote:
[a bunch of ad-hoc parsing with scanf]

Alternatively, use a lexer generator such as GNU flex to parse such
files in the desired manner, detect malformed input and report it
correctly, and all such other nice stuff with a smaller description and
less chance of error. Your program will run faster too. You can then use
more specific conversion functions like atof on the individual tokens.


nit-wit.

Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
13576
by: RAJASEKHAR KONDABALA | last post by:
Hi, Does anybody know what the fastest way is to "search for a value in a singly-linked list from its tail" as oposed to its head? I am talking about a non-circular singly-linked list, i.e., head and tail are not connected. Of course, recursive function aproach to traverse the list is one way. But, depending upon the list size, it could overrun the stack pretty fast.
5
6061
by: John N. | last post by:
Hi All, Here I have a linked list each containing a char and is double linked. Then I have a pointer to an item in that list which is the current insertion point. In this funtion, the user hits the right and left keys to move this insertion point (cursor) Here is the problem:
7
2613
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's children - when a child is fork()ed its pid is added to the linked list. I then have a SIGCHLD handler which is supposed to remove the pid from the list when a child exits. The problem I'm having is that very very occasionally and seemingly...
4
3060
by: Psibur | last post by:
Hello, trying to get back into c and was having issue with reading a simple text file with an aribtrary # of lines with 3 int's per line, with the eventual purpose of putting each int into an element of an array (eventually will be other things, but I'm sticking to int's for now). I.e.: 0 1 1 1 1 1 2 1 1 etc... The problem is it'll read and print all but the last line. Is there
7
5458
by: Thomas Sourmail | last post by:
Hi, I hope I am missing something simple, but.. here is my problem: I need my program to check the last column of a file, as in : a b c d target ref 0 0 0 0 1 a 1 0 0 0 1.5 b 2 0 0 0 2 c
10
2518
by: Ben | last post by:
Hi, I am a newbie with C and am trying to get a simple linked list working for my program. The structure of each linked list stores the char *data and *next referencing to the next link. The problem I get is that I am trying to link a struct that I have defined and its refusing to link. I have tried casting my struct into char * but attempts to cast it back to its original struct to access its contents only seg faults.
3
472
by: Little | last post by:
Could someone tell me what I am doing wrong here about declaring mutiple double linked lists. This is what the information is for the project and the code wil be below that. Thank your soo much for your assitance in helping me solve this problem. Information: Create 4 double linked lists as follows: (a) A double linked list called NAMES which will contain all C like
11
477
by: bofh1234 | last post by:
Hello, I am having a problem with linked lists. My program is based on a client server model. The client sends some packets of data to the server. The server reads those packets and is supposed to store the data in a linked list. It looks like everything works except for the fact that the linked list only stores the last value sent and the number of nodes in the linked list is way to high. For example the client sends 4 create...
37
4979
by: PeterOut | last post by:
I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2). I am not sure if this is a C, C++ or MS issue but fscanf has been randomly hanging on me. I make the call hundreds, if not thousands, of times but it hangs in different places with the same data. The offending code follows. ReadFile(char *csFileName) { float fFloat1, fFloat2;
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9865
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8873
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3965
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3565
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.