• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 385
  • Last Modified:

simulating a behaviour similar to router

I want to create a program in which i have three tables A,B,C.

Each table has info like counter. counter for A is 1, counter for B is 2 and counter for C is 3.

Table A is connected to B but not C, C is connected to B but not A. I want the program to run in three different processes and display the info for counters for all tables in their respective processes. Could someone guide me on how I could write a program that would display info of table itself, n the other two tables in process 1

eg: A counter=1, B counter=2, C  counter=3
    B counter=2, C counter=3, A counter=1
    C counter=3, A counter=1, B counter=2


I am a beginner in C, any advice is appreciated.

Thanks
0
surphar
Asked:
surphar
  • 20
  • 14
1 Solution
 
rajeev_devinCommented:
Try something and post the code if you are facing some difficulty.
0
 
Infinity08Commented:
Here's a few tips that will help you with this task :

1) for communication between your three processes, i suggest the TCP/IP protocol stack. It's easy to use, and is very general. Just create a connection between A-B  and B-C, which will represent the network.

2) B will act as a router between A and C (as A and C are not directly connected).

3) the data packets sent between the three processes should consist of a header and a data part. Make the header contain the source and destination ID's (unique ID's !!). The data part should contain a request for the counter value.

4) add a routing table to each process which says on which connection to send a packet to reach a certain destination. eg. A will have to send to B to reach C. Routing table for A (format : dest -> route) :

    all -> connection 1 (towards B)

routing table for B :

    A -> connection 1 (towards A)
    B -> connection 2 (towards B)

5) if a packet arrives in a certain process that is not destined for that process, the destination should be looked up in the routing table, and the packet forwarded on the correct connection.


By following these tips, you'll quite accurately model the internet/network model.

Try to do this, and when you have problems, show us what you have, and what problem you have with it, and we'll be glad to help you out.
0
 
surpharAuthor Commented:
Ok as a first step here's what I am trying to do:
1) Create a pipe, read data from a variable. Write this data to the pipe. Send a message two file2 that pipe is ready to be read. All this in one file
2)Another file which will display message "reading from pipe". Reads until it's done.

to achieve this what I am trying to do is:
create global vars open/close ends of the pipe for writing. Now I know I am wrong here cuz it gives me an error on compilation.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

extern  int     fd[2], nbytes;
extern  pid_t   childpid;
extern  char    string[] = "Hello, world!\n";
extern  char    readbuffer[80];

main(void)
{

        pipe(fd);
       
        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, strlen(string));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

        }

}

From another file I would like to read from the pipe. Now I don't know how to do this:
It'll be something like this but don't know if it'll work.
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);

The idea behind doing this is that if I can read from a var, write to a pipe and read from pipe. Then I can go ahead with the "actual" program. Note: I could have done this by forking all in one file but here I need to show the output i.e. "sending...." "receiving...." in different shells thats why I have to have to separate files

Any help is appreciated.

Thanks
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Infinity08Commented:
Why do you define the globals as extern ???

What compilation error do you get ?
0
 
surpharAuthor Commented:
so that the globals are accessible from outside(other files) as well. I have to update the values for these globals and the other processes have to know the values for these variables all the time. I do not have the compiler at this machine so I can't post the error just yet. Will do so later during the day.

Thanks
0
 
Infinity08Commented:
I think you're confused on the use of the extern keyword. The extern keyword tells the linker that the data can be found in another compilation unit. Example :

/* file1.c */
int test;

/* file2.c */
extern int test;

the test integer will be in the compilation unit for file1.c (file1.o), and file2.c refers to file1 when it needs to use the test integer.

Second : a variable won't be accessible by other processes by use of the extern keyword. It is used at link-time only, and thus for one executable only (including all others that have been linked into the executable).

So, unless these values are defined in another compilation unit of the same project, don't use the extern keyword :

int     fd[2], nbytes;
pid_t   childpid;
char    string[] = "Hello, world!\n";
char    readbuffer[80];
0
 
surpharAuthor Commented:
Hello Infinity,

Thank you for your pointers. Could you please guide me on how could I link two processes. Because I think that I am going in the wrong direction.

To make this more clear I won't be having a "real" address to connect to. I looked at the TCP/IP protocols and they would do the work, had it been real addressing!

What really doesn't click to me is that how am I supposed to connect the server and the clients.

I'll look more and keep you all updated.

Thanks for any ideas.
0
 
Infinity08Commented:
>> To make this more clear I won't be having a "real" address to connect to. I looked at the TCP/IP protocols and they would do the work, had it been real addressing!

If you have the TCP/IP protocol stack installed on your system (which is more than likely), and have a network card (doesn't need to be connected), then you can make use of TCP/IP to let your programs communicate. Just use address 127.0.0.1 (loopback to the own PC), and the port the other application is listening on, and that's it.

>> What really doesn't click to me is that how am I supposed to connect the server and the clients.
If you choose to make use of TCP/IP (which makes things quite easy), then just let your different processes listen on a certain port. Then you can make a connection on that certain port to send data to the process you want.

for example :

process 1 listens on : 60001
process 2 listens on : 60002 and 60003
process 3 listens on : 60004

The available "connections" are from process 1 to process 2 and from process 2 to process 3 :
____                               ____                              ____
| 1 |  60001<---->60002  | 2 |  60003<---->60004  | 3 |
------                              ------                              ------
0
 
surpharAuthor Commented:
I doubt I'll be able to use localhost since I am using school computers. I'll have to check with sysadmins if it'll be OK. But if not I was thinking if alternatively I could do this using execl()? Keep doing execl() for all the links (one at a time).

Thanks
0
 
surpharAuthor Commented:
In addition to execl() I was thinking of creating my own structures for the routers. So they'll have addressing info.
0
 
Infinity08Commented:
If you are looking for an alternative way of doing InterProcess Communication (IPC), then check this page for a list of generally used ways of communicating between processes :

http://en.wikipedia.org/wiki/Inter-process_communication

The one i suggested was using sockets, but as you see there are a lot more ways. Either shared memory or pipes seem to best fit your requirements (after sockets). But you'll be limited by the OS you're using.

Pipes conceptually model router behaviour better than shared memory, so that might be your best option. From the code you showed earlier, this is indeed the way you're doing it.

For an example (as well as the reference manual entries), check out this page :

http://www.opengroup.org/onlinepubs/009695399/functions/pipe.html
0
 
surpharAuthor Commented:
So in continuation with the current thread, here is what I am doing.

Sending messages from routers B, A and C to Networks 54 and 02. And update routing tables.

Consider this scenario
B <--> NET54 <--> A <--> NET02 <-->C

Initial Routing table for A

Network    HopCount NextHop
NET02      1       --
NET54      1       --

Initial Routing table for B

Network    HopCount NextHop
NET54      1       --

Initial Routing table for C

Network    HopCount NextHop
NET02      1       --

All messages are communicating one at a time.

So B sends a message to A -- Update their routing tables
A sends a message to C -- Update their routing tables

All these routing tables are in 3 separate files
When B sends a message to A the routing table for B becomes

Network    HopCount NextHop
NET54      2       --
i.e. add 1 to the count

after that I update the routing table for A which after applying my logic becomes
Network    HopCount NextHop
NET02      1       --
NET54      1       B

A sends message to C
A
Network    HopCount NextHop
NET02      2       B
NET54      2       --

C
Network    HopCount NextHop
NET54      2       B
NET02      2        A

A sends message to B
Table for A
Network    HopCount NextHop
NET54     3        B
NET02     3        --

Table for B is
Network    HopCount NextHop
NET54     2       A
NET02      3       A

C sends message to A

Table for C becomes
Network    HopCount NextHop
NET54      3       B
NET02      3       A

Table for A becomes
Network    HopCount NextHop
NET54      3       B
NET02      1       C

So the challenges that I face here are:
1) When B sends message to A I have to increment the hop count in table for B
and leave third column as --
2)When A receives a message from B it checks if the line one it it's own table is the same as

line 1 from the original table for B. If it is no change and make the third column name as "B"
Then when its done reading the rows from table B it leaves the rest of the rows in table A as is.

I need to figure out how could I get the two tables to be updated and once I update it I have to

continue sending messages i.e. A--> C, A-->B, C-->A

The way I was thinking to do this was as below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#define PIPE_RD 0
#define PIPE_WR 1

int main(void)
{
  int fds[2];
pipe(fds);
if(fork()){
/update the table for router B i.e. increment hop counts */
/* send message to A */
dup2(fds[1],STDOUT_FILENO);
/* got message from B. Facilitate a way to send in "B" */

execlp("test2","test2",NULL);
return 0;
}

/*test2.c*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

#define PIPE_RD 0
#define PIPE_WR 1

main(void)
{
in here I need to check table for B and compare it's entries to the ones in table for A.
Increment them or modify them as needed

once that is done I need to send a message from A to C
so again execl or something
Basically behaviour similar to the previous one
}

I understand the concept but syntactially I am having problems in putting this all together.  Can Somebody tell me how I could do this?

Thank You
0
 
surpharAuthor Commented:
Actually I figured how to read from the file. But I have problems modifying the text file.

I want to be able to modify a particular record.

My text file contents are:
NET09     1     --

So after reading in the file if I find NET09 I want to replace 1 by a 2.

In my code i have:
routerD.hopCount=routerD.hopCount++;
while (fread(&routerD.hopCount,sizeof(routerD.hopCount),1,fp)==1)
{if(strcmp(routerD.netID,"NET09")==0)
{
   fseek(fp,-sizeof(routerD.netID),SEEK_CUR);
   fwrite(&routerD.hopCount,sizeof(routerD.hopCount),1,fp);
 
}}
/*So the modified text file contents will be:
NET09     2     --
*/
Unfortunately this doesn't do the trick.

Would someone please tell me how I could look for a particular record and modify the field next to it?

Thanks
0
 
surpharAuthor Commented:
Acutally what I need to do is: if routerD.netID="NET09" and routerD.hopCount=1 then in file change 1 to 2 where netID=NET09 and hopCount was 1

0
 
surpharAuthor Commented:
Can somebody please tell me how to update the text file once I have done reading.
What the problem is that I need to locate the NET09 in the text file and then change the corresponding count with it i.e. 1 to 2

All i want to do is change the next hop count from 1 to 2
Here's all my code
========
My text file contents are:
NET09     1     --
NET19     1     --


se.h
========
typedef struct {
     char netID[7];
        int hopCount;
        char nextHop[2];
        }Routers;
==============
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "se.h"

Routers routerD;
int main()
{

char buff[10];

int rdr;
int loop = 0;
FILE *fp;
FILE *fp1;
fp = fopen("tblD.txt","r+");
rdr = fgetc(fp);

/*read network ID*/
while(!feof(fp)){
while((rdr == '\n') && (rdr != EOF))
rdr = fgetc(fp);
/* if(rdr == EOF) return 0;
*/
while((rdr != '\n')&&(rdr!='\t') && (rdr != EOF)){
buff[loop++] = rdr;
rdr = fgetc(fp);
}
buff[loop]=0;
strcpy(routerD.netID,buff);
printf("\n");
printf("%s",routerD.netID);
/*
if(rdr==EOF) return 0;
*/
loop=0;
/* read hop count
 */  while( (rdr != '\n') &&(rdr =='\t') && (rdr != EOF)) {
      buff[loop++] = rdr;
      rdr = fgetc(fp);
/*
        if(rdr==EOF)return 0;
*/
   }
 buff[loop]=0;

while((rdr != '\n') && (rdr != '\t')&&(rdr != EOF)){
buff[loop++]=rdr;
rdr=fgetc(fp);
}
 buff[loop]=0;
   routerD.hopCount =  atoi( buff );
/*   if( rdr == EOF ) return 0;
*/
printf(" ");
printf("%d",routerD.hopCount);


loop=0;
/* read next hop */
 while( (rdr != '\n') &&(rdr =='\t') && (rdr != EOF)) {
      buff[loop++] = rdr;
      rdr = fgetc(fp);
  /*      if(rdr==EOF)return 0;
*/  
}
 buff[loop]=0;
while((rdr != '\n') && (rdr != '\t')&&(rdr != EOF)){
buff[loop++]=rdr;
rdr=fgetc(fp);
}
 buff[loop]=0;
strcpy(routerD.nextHop,buff);
printf(" ");
printf("%s",routerD.nextHop);
loop=0;
/*if( rdr == EOF ) return 0;*/
if(rdr==EOF) break;
}
/*return 1;*/
/*
routerD.netID

routerD.netID = ReadFromFile
routerD.hopCount = ReadFromFile
routerD.nexthop = ReadFromFile

PrintRouterD
routerD.hopCount = routerD.hopCount++;
RouterD.data write to the textfile

sendmessagetoRouterB
sendmessageTo RouterC
*/


printf("%c",routerD.netID);
printf("%d",routerD.hopCount);

/*fflush(stdin);
*/
fp1=fopen("tblD1.txt","w");
if(fp1==NULL)
{
printf("Erorr");
}
else
{
printf("yes");
}
/*
fseek(fp1,0,SEEK_END);
fwrite(&routerD,sizeof(routerD),100,fp1);
*/
fprintf(fp1,routerD.netID);
/* fprintf(fp1,routerD.hopCount); */
fprintf(fp1,routerD.nextHop);
fclose(fp1);

return 1;
}


Any help is greatly appreciated.

Thank You
0
 
Infinity08Commented:
You can't easily modify a text file ... you'll have to read its contents, make the changes in memory, and write the whole file back to the disk.
When there are frequent changes to the file, i suggest keeping the data in memory, rather than making changes to a file every time.

That being said, I'm not sure what you're trying to achieve in changing the routing tables all the time ... A routing table should be (semi-)static. It describes the network, and as long as there are no changes to the network setup, the routing table shouldn't change.

As I tried to explain earlier, in the message you send, you should include the destination. When a message arrives at a certain router, it checks its routing table to see which link corresponds with the destination found in the message, and it forwards the message on that link.
0
 
surpharAuthor Commented:
Hello Infinity,

Initially in this case the routing table for D has info about the neighbors. D sends message to neighbors and the hopcount for its routing table network increases by one all the time. Once that is done the neighbors check the routing table for D and modify their own routing table info based on that.

B<--> NET06 <---> C <--> NET09 <--> D<--> NET10
Table for D
NET09  1 --
NET10  1 --

Table for C
NET09 1 --
NET06 1 --

D sends message to C
D changes to
NET09 2 --
NET10 2 --

C changes to
NET09 1 D
NET06 1 --

The routing tables for all the routers have been given fixed values and they change their values according to the RIP algorithm.

Yes I will include the destination in the message but before I do that I have to change the routing table for D.

Could you please guide me on how I could keep data in memory and change the file.
the challenge I have here is finding out the right networkid and then change the corresponding hopcount.

Do you mean I should keep it's info in a struct or something and then write the struct to the file once I've updated the hopcounts?

One thing that I noticed was that when I say routerD.netID = charFromFile. The value gets printed fine, but as soon as I close the file the value from the variable routerD.netID becomes 0.

Please advise
0
 
Infinity08Commented:
>> The routing tables for all the routers have been given fixed values and they change their values according to the RIP algorithm.
That's fine ... You might try to get it to work with fixed routing tables first though ... and once everything works, you can add network change detection and optimization protocols like RIP.

>> Could you please guide me on how I could keep data in memory and change the file.
From what I understand, you want to access the files from different processes at the same time ? This is possible, but you'll have to implement same safeties so there can be no deadlocks or data inconsistencies etc.

>> the challenge I have here is finding out the right networkid and then change the corresponding hopcount.
If you foresee that this happens regularly, then it's maybe better to look into shared memory instead of files (or some other faster way of sharing data)

>> Do you mean I should keep it's info in a struct or something and then write the struct to the file once I've updated the hopcounts?
Yes

>> One thing that I noticed was that when I say routerD.netID = charFromFile. The value gets printed fine, but as soon as I close the file the value from the variable routerD.netID becomes 0.
If you read a character from a file into a local variable, and then close the file, the local variable will still contain the character. Can you show the relevant piece of code where you noticed this behaviour ?
0
 
surpharAuthor Commented:
yes this is where I store the values
strcpy(routerD.nextHop,buff);
 routerD.hopCount =  atoi( buff );

when I print values for routerD.nextHop and routerD.hopCount it comes with special characters!!

You may refer to the code I posted recently. I think whats happening is that once it reaches end of file, it discards everything.

0
 
surpharAuthor Commented:
Hi Infinity,

Assuming I created an array of Routers. i.e. Routers routerD[10]

So I first read info from file and save in position 1
strcpy(routerD[1].nextHop,buff);
 routerD[1].hopCount =  atoi( buff );

Then I copy data from routerD[1] to routerD[2] by router[2] = router[1] //correct me if I am wrong

then router[2].hopCount = router[2].hopCount++ then write to the data file.

When I write to the data file, I need the data to be tab separated.
router[2].netID       router[2].hopCount ??????
then go to next row n do the same

How Can I introduce a tab?

Thank You
0
 
Infinity08Commented:
First of all : you're doing the file reading waaay too complicated. There's no reason to read in character by character. You can simply do formatted reading as you know the format the text file is in. Check the fscanf() function for example :

http://www.cplusplus.com/ref/cstdio/fscanf.html

And fprintf() for writing back to the file :

http://www.cplusplus.com/ref/cstdio/fprintf.html

Example :

char str[128];
int i;
fp = fopen("file.txt", "r");
fscanf(fp, "%s\t%d\n", &str[0], &i);
fclose(fp);
fp = fopen("file.txt", "w");
fprintf(fp, "%s\t%d\n", str, i);
fclose(fp);

Once you've made the code easier, you'll have a better oversight, and you'll spot any problems in the code very fast ...
0
 
surpharAuthor Commented:
Infinity,
I took ur advise and am using scanf now. The program is much simpler but now I am stucked in copying structs!!!

typedef struct {          
     char *netID[7];
        int hopCount;                    
        char *nextHop[2];                    
        }Routers;

Routers one;
Routers two;
I read from file and set one.netID = something, one.hopCount = something and etc

How can I set two the same as one?

Please advise
0
 
surpharAuthor Commented:
Hello Infinity,

With fscanf and fprintf, scanf works fine but fprintf only writes the value of the last read line!

This is what I am doing.

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "se.h"

Routers routerD;

int main()
{
int i=0;
Routers tt;

FILE *fp;
FILE *fp1;
fp = fopen("tblD.txt","r");
/*read network ID*/

 while(!feof(fp)){


fscanf(fp,"%s\t%d\t%s\n",&routerD.netID[0],&routerD.hopCount,&routerD.nextHop[0$
 
strcpy(&tt.netID[0],&routerD.netID[0]);
strcpy(&tt.nextHop[0],&routerD.nextHop[0]);
tt.hopCount = routerD.hopCount;
tt.hopCount = tt.hopCount++;
 
fp1=fopen("tblD2.txt","w");

/* fprintf(fp1,"%s\t%d\t%s\n",tt.netID,tt.hopCount,tt.nextHop);
*/

fprintf(fp1,"%s\t%d\t%s\n",routerD.netID,routerD.hopCount,routerD.nextHop);
        printf("%s\t%d\t%s\n",routerD.netID,routerD.hopCount,routerD.nextHop);

}

return 1;
}

Please advise. I have to finish this today!!!

Thanks a lot
0
 
surpharAuthor Commented:
Ok i figured that out!

However here's what I need to do now:

say i have to text files one text file has:
net06    1 --
net25    1 --
other text file has
net06    1 --
net24    1 --
i need to compare the two files and if i find any thin in file one thats not in file 2 then i add it to file 2 i.e.
net06    1 --
net24    1 --
net25    1 --

In order to do this I am trying to save values read from the file first column

int rdr;
int loop = 0;

FILE *fp;
FILE *fp1;
char arr[50];

fp = fopen("tblE.txt","r+");

for(loop=0;loop++;loop<50)
{
fscanf(fp,"%c",arr[loop]);
}
fclose(fp);
printf("%d",loop);
loop=0;

printf("%s",&arr);

The problem is, it's not saving it to the array properly. Can someone tell me how could i write data properly to an array after reading it from file?

Thanks
0
 
Infinity08Commented:
Some important notes :

1) don't use this struct definition :

    typedef struct {          
      char *netID[7];
      int hopCount;                    
      char *nextHop[2];                    
    }Routers;

but use this one :

    typedef struct {          
      char netID[7];
      int hopCount;                    
      char nextHop[2];                    
    }Routers;

You don't want an array of strings, you want one string.

2) this is overkill :

    tt.hopCount = tt.hopCount++;

use just this :

    tt.hopCount++;

3) don't forget to fclose() the files !!!

4) Don't forget that fscanf() requires the addresses of the target variables, not their values :

    fscanf(fp,"%c",arr[loop]);

should be :

    fscanf(fp,"%c",&arr[loop]);

5) for a printf(), you need the value itself, so :

    printf("%s",&arr);

is better as :

    printf("%s",arr);



Regarding your last problem :
>> The problem is, it's not saving it to the array properly. Can someone tell me how could i write data properly to an array after reading it from file?

The trick is to use a struct for each line in the file :

    typedef struct {          
      char netID[7];
      int hopCount;                    
      char nextHop[2];                    
    }Routers;

and then, for each router, define an array like this :

    Routers router1[5];
    Routers router2[5];
    /* ... */

note that in this case max. 5 lines can be present per router.

That way, you can read in line per line and store them in the array :

    fscanf(fp, "%s\t%d\t%s\n", &router1[0].netID[0], &router1[0].hopCount, &router1[0].nextHop[0]);
    fscanf(fp, "%s\t%d\t%s\n", &router1[1].netID[0], &router1[1].hopCount, &router1[1].nextHop[0]);
    /* ... */

Of course it's better to do this in a loop, but I'll leave that up to you.

When the file is read, you'll have all the data of the file in the router1 array. You can do the same thing for the other routers, and then you can compare, copy, or whatever you want to do with the data.
When you're done manipulating the data, you just write all of it back to the files again.
0
 
surpharAuthor Commented:
Thank you for your time infinity, I used the idea you provided but it still doesn't save any values to the structs. Here's my source:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "se.h"

Routers routerD;
int main()  
{

char buff[10];

int rdr;
int loop = 0;

FILE *fp;
FILE *fp1;
char arr[50];
Routers router1[5];
pidB=fork();
/*
if(pidB){*/
fp = fopen("tblE.txt","r+");
/* fp1=fopen("tblTmpNetID.txt","w");
*/

for(loop=0;loop++;loop<5)
{
fscanf(fp,"%s\t%d\t%s\n",&router1[loop].netID[loop],&router1[loop].hopCount,&router1[loop].nextHop[loop]);
}
fclose(fp);

loop=0;
for(loop=0;loop++;loop<5)
{
printf("%s\t%d\t%s\n",&router1[loop].netID[loop],&router1[loop].hopCount,&router1[loop].nextHop[loop]);
}



return 1;
}
=====
se.h
=====
typedef struct {          
     char netID[7];
        int hopCount;                    
        char nextHop[2];                    
        }Routers;


Could you tell me where could I be wrong?

Thanks
0
 
Infinity08Commented:
A few problems :

1) This is the wrong way to use a for loop :

      for(loop=0;loop++;loop<5)

This is the correct way :

      for(loop=0;loop<5;loop++)

So, the first part is the initialization, the second part is the continue condition, and the third part is the incrementor.

2) In the fscanf(), you want to read in two strings and 1 integer value. You want to read them into an array of structs (these structs contains two strings and one int each). The way you did it :

      fscanf(fp,"%s\t%d\t%s\n",&router1[loop].netID[loop],&router1[loop].hopCount,&router1[loop].nextHop[loop]);

is incorrect ... you want to read into the array element with index loop (router1[loop]). That element is in fact a struct, and from that struct you want to read in the parameters of that struct :

      router1[loop].netID
      router1[loop].hopCount
      router1[loop].nextHop

But, fscanf() expects the address of these, so we have to pass :

      &(router1[loop].netID)[0]
      &(router1[loop].hopCount)
      &(router1[loop].nextHop)[0]

added ()'s for clarity.

3) A printf however doesn't expect addresses, but the actual values, su you have to pass it :

      router1[loop].netID
      router1[loop].hopCount
      router1[loop].nextHop

4) The structure definition as you have it :

      typedef struct {
        char netID[7];
        int hopCount;
        char nextHop[2];
      }Routers;

limits the size of netID to 6 characters (7-th is for '\0'), and limits nextHop to 1 character (2-nd is for '\0'). Take this into account !!!!
0
 
surpharAuthor Commented:
Hello Infinity

I changed the code as per your suggestion and have it this way now:

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


void main()  
{

char buff[10];

int rdr;
int loop = 0;

FILE *fp;
FILE *fp1;
char arr[50];
Routers router1[5];

/*
if(pidB){*/
fp = fopen("tblE.txt","r+");
/* fp1=fopen("tblTmpNetID.txt","w");
*/

for(loop=0;loop<5;loop++)
{
fscanf(fp,"%s\t%d\t%s\n",&(router1[loop].netID)[loop],&(router1[loop].hopCount),&(router1[loop].nextHop)[loop]);
}
fclose(fp);

loop=0;
for(loop=0;loop<5;loop++)
{
printf("%s\t%d\t%s\n", router1[loop].netID,router1[loop].hopCount,router1[loop].nextHop);
}

}
It prints 0 all the time.
Plus I didnt' get what you said in point # 4 above.

Please comment
0
 
Infinity08Commented:
>> fscanf(fp,"%s\t%d\t%s\n",&(router1[loop].netID)[loop],&(router1[loop].hopCount),&(router1[loop].nextHop)[loop]);

    &(router1[loop].netID)[loop]

let's de-compose this :

    router1[loop]

is the struct at position "loop" in the array router1.

    router1[loop].netID

is the parameter netID (a C string) of that particular struct.

Now, we want the address of the first character of this string, so we do :

    &(router1[loop].netID[0])

Note two things :

1) I mistyped in my earlier point 2). It should have been :

      &(router1[loop].netID[0])
      &(router1[loop].hopCount)
      &(router1[loop].nextHop[0])

watch out for the location of the ending )

2) you used the address of the character at index "loop" instead of the first character ... this will start writing in the middle of your string, and is not what you want.



And finally :
>> Plus I didnt' get what you said in point # 4 above.
Some clarification : a C string consists of several characters, terminated by a NULL character ('\0'). So, the string "hello" consists of 6 characters (the 5 characters of the word hello, plus one character for the terminator) :

    'h', 'e', 'l', 'l', 'o', '\0'

When reserving space for a string like this :

    char str[7];

you reserve space for 6 characters plus 1 terminator. So, the string can max. contain 6 characters.

Apply this to your struct to see that the first can contain 6 characters, and the last only 1.

When writing to a C string, there's NO check for the length, so if you try to write a string of 10 characters into a string that can only hold 6, you'll overwrite memory that is not owned by the string, and will get weird errors at least (maybe even a coredump).

The solution is to either allocate enough space for any string you might put in it, or check the size of the string before you write it.
0
 
surpharAuthor Commented:
Hello Infinity,

In addition to printing 0's, i've also added a part where router2 will prints to another file.

It prints 0 all the time.
Plus I didnt' get what you said in point # 4 above.

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


void main()  
{

int loop = 0;
typedef struct {          
     char netID[7];
        int hopCount;                    
        char nextHop[2];                    
        }Routers;

FILE *fp;
FILE *fp1;
char arr[50];
Routers router1[5];
Routers router2[5];

fp = fopen("tblE.txt","r+");

for(loop=0;loop<5;loop++)
{
fscanf(fp,"%s\t%d\t%s\n",&(router1[loop].netID)[loop],&(router1[loop].hopCount),&(router1[loop].nextHop)[loop]);
}
fclose(fp);

loop=0;
for(loop=0;loop<5;loop++)
{
printf("%s\t%d\t%s\n", router1[loop].netID,router1[loop].hopCount,router1[loop].nextHop);
}

/* memcpy(&router1,&router2,sizeof(ROUTERS));
*/
router2=router1;
loop=0;
for(loop=0;loop<5;loop++)
{
printf("%s\t%d\t%s\n", router2[loop].netID,router2[loop].hopCount,router2[loop].nextHop);
}
fp1=fopen("test.Txt","w");
loop=0;
for(loop=0;loop<5;loop++)
{
fprintf(fp1,"%s\t%d\t%s\n", router2[loop].netID,router2[loop].hopCount,router2[loop].nextHop));
}
close(fp1);
}
Can you please advise where I am doing it wrong!!! It's really urgent!!

Thanks
0
 
Infinity08Commented:
Read my last post ...
0
 
surpharAuthor Commented:
And how would I go on copying info from one struct to another?

memcpy(&router1,&router2,sizeof(ROUTERS));

or router2=router1;
0
 
Infinity08Commented:
router1 and router2 are arrays, so you'll have to take that into account. the memcpy is a good solution, but you'll have to adjust the size to copy the whole array.
0
 
surpharAuthor Commented:
Hello Infinity08,

I would like to thank you for your support and help.
Enjoy the points :)

--
Surphar
0
 
Infinity08Commented:
No problem ... if you have any further questions or problems regarding this, just post them in here.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 20
  • 14
Tackle projects and never again get stuck behind a technical roadblock.
Join Now