creating an array with fscanf

Hi all,

I am trying to read data from a file and assign it to a permanent spot in an array. Here is the problem area of my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <string>
#include <iostream>
#include <typeinfo>
using namespace std;

FILE *unit1;

int main()
{
	
     unit1=fopen("calc_bands.tab", "r");
     
     char * name[13000], xname [13000], c[13000], band[100];
     double value, r;
     int N, flag, I, J;
     
     N=0;
     I=0;
     
     while(!feof(unit1))
     {
          fscanf(unit1, "%s %s %lg", xname, 
                band, &r);     
          if(N==0)
          {
               N=1;
               name[N]=xname;
          }

          flag=0;
          for(J=1; J<=N; J++)
          {
               //problem is this is always true! 
               if(xname==name[J]) 
                    flag=J;
          }
          if(flag==0)
          {
               N++;
               name[N]=xname;
               flag=N;
          }
          I++;
     }
     cout << "done with N = " << N << "stars \n";
     fclose(unit1);
     return 0;
}


where calc_bands.tab looks like:
PM_I00006+1829.fits(1) CaH1 1.68245E-13
PM_I00006+1829.fits(1) CaH2 1.75756E-13
PM_I00006+1829.fits(1) CaH3 1.91924E-13
PM_I00012+0659.fits(1) CaH1 7.18074E-16
PM_I00012+0659.fits(1) CaH2 8.58012E-16
PM_I00012+0659.fits(1) CaH3 1.57750E-15

The problem is that xname always equals name[J]. What I want to happen is that name[J] should store a char sequence like "PM_I0000....." in the Jth position. When I run this code and cout << name[2], for example, it always ends up the as the last "xname" read. Should I be using a vector instead like
vector <char> name? I have looked at the reference for vectors and tried to use a vector but I am still having problems. Any suggestions??

Im new to c++ and programming in general. I apologize in advance for any stupid questions.
Last edited on

Hi, I have tested your code and modified it as shown below, I think I am getting
the desired result with N = 2stars

The first change is that name is a char** and I have initialized it to 100 pointers.
xname, c, band are setup as char pointers (assuming they are work variables)

the other changes in the code are

memcpy(name[N],xname,strlen(xname)+1);
which copies xname into name[N] you cant use name[n] = xname,
because it only copies the pointer not the contents.

and same with strcmp(xname,name[J]) == 0
compares the contents and not the pointer

hope this has helped you
Shredded


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <string>
#include <iostream>
#include <typeinfo>
using namespace std;

FILE *unit1;

int main()
{
	
     unit1=fopen("calc_bands.tab", "r");
     
     
	 char** name;			//CHANGED from here
	 
	name = new char*[100];
	
	for (int i=0;i<100;i++)
	{
		name[i] = new char[32];
	}

	char*	xname = new char[32];
	char*	c = new char[32];
	char*	band = new char[32];	// to here

	

     double value, r;
     int N, flag, I, J;
     
     N=0;
     I=0;
     
     while(!feof(unit1))
     {
		
          fscanf(unit1, "%s %s %lg", xname, 
                band, &r);     
          if(N==0)
          {
               N=1;
               memcpy(name[N],xname,strlen(xname)+1);	// CHANGED
          }

          flag=0;

          for(J=1; J<=N; J++)
          {
               //problem is this is always true! 
               if(strcmp(xname,name[J]) == 0)		// CHANGED
                    flag=J;
          }
          if(flag==0)
          {
               N++;
               name[N]=xname;
               flag=N;
          }
          I++;
     }
     cout << "done with N = " << N << "stars \n";
     fclose(unit1);
     return 0;
}
Wow thanks it finally works!

Is fgets() better to use in this situation than fscanf()?

I read that using feof() is a bad idea, should I change the while loop to a for loop and just use the number of lines as the end parameter?

On that note, someone in one of the other forums suggested against using FILE*, opting for ifstream instead. Any suggestions?

Hi again,

I dont normally use FILE* {instead use win32 api's CreateFile} but it would seem
that FILE* is suitable for console applications {also independant of OS}. I havent
used ifstream but ill take a look at it and see what can be done, because I do get
the depriciated message with fopen {cant see it dissapearing just yet}

as for fgets its main advantage is that it can be used to tell EOF

could be used like this

1
2
3
4
5
6
7

        char*  buffer = new buffer[32];

        while (fgets(buffer,32,file) == buffer)
	{
             // do stuff here like sscanf
        }


as for which is best that is upto the individual coder

Shredded
Topic archived. No new replies allowed.