Problem with reading the input parameters from a .txt file under the Linux

Hi, I am Rita. And I am now trying to run my C program under the Linux system. Now I can compile and run the program under the Linux but the problem is that when I run my program under the windows system, it can read the input parameters from .txt file. But when I run my program under the Linux system, it can not read the parameters in a right way. All the parameters readed by Linux system are wrong.

So does anyone have some suggestions?

For example:
when the program run under the Windows system, the input parameters are:
The number of runs: 9
The Photon numbers: 50
dz dr dt: 50E-3 10E-3 6.283E-009

When the program run under the Linux system, the input parameters display on the screen are:

the number of runs: 1
the photon numbers:4196067
dz dr dt: 2.07267E-317 2.122E-314 4.5460E+150

I really do not know why?
Could you post your code? Use the code tags (see http://www.cplusplus.com/forum/articles/1624/ for how to do this) and someone will have a look

EDIT: Although looking at the numbers I should think it's not actually getting the data out of the file. Those numbers look like uninitialised variables. Make sure the file is where the code thinks it is and that the permissions allow it to be opened.
Last edited on
Thank you for your advice. I attached parts of my codes.

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/***********************************************************
 *	Get a filename and open it for reading, retry until 
 *	the file can be opened.  '.' terminates the program.
 *      
 *	If Fname != NULL, try Fname first.
 ****/
FILE *GetFile(char *Fname)
{
	char * myName = "TEMPLATE.mci";
  FILE * file=NULL;
  Boolean firsttime=1;
  
  do {
    if(firsttime && Fname[0]!='\0') { 
	  /* use the filename from command line */
      firsttime = 0;
    }
    else {
      printf("Input filename(or . to exit):");
      //scanf("%s", Fname);
      firsttime = 0;
    }

    //if(strlen(Fname) == 1 && Fname[0] == '.') 
    //  exit(1);			/* exit if no filename entered. */
    
    //file = fopen(Fname, "r");
	file = fopen(myName, "r");
  }  while(file == NULL);
  
  return(file);
}

/***********************************************************
 *	Kill the ith char (counting from 0), push the following 
 *	chars forward by one.
 ****/
void KillChar(size_t i, char * Str)
{
  size_t sl = strlen(Str);
  
  for(;i<sl;i++) Str[i] = Str[i+1];
}

/***********************************************************
 *	Eliminate the chars in a string which are not printing 
 *	chars or spaces.
 *
 *	Spaces include ' ', '\f', '\t' etc.
 *
 *	Return 1 if no nonprinting chars found, otherwise 
 *	return 0.
 ****/
Boolean CheckChar(char * Str)
{
  Boolean found = 0;	/* found bad char. */
  size_t sl = strlen(Str);
  size_t i=0;
  
  while(i<sl) 
    if (Str[i]<0 || Str[i]>255)
      nrerror("Non-ASCII file\n");
    else if(isprint(Str[i]) || isspace(Str[i])) 
      i++;
    else {
      found = 1;
      KillChar(i, Str);
      sl--;
    }
  
  return(found);	
}

/***********************************************************
 *	Return 1 if this line is a comment line in which the 
 *	first non-space character is "#".
 *
 *	Also return 1 if this line is space line.
 ****/
Boolean CommentLine(char *Buf)
{
  size_t spn, cspn;
  
  spn = strspn(Buf, " \t");	
  /* length spanned by space or tab chars. */

  cspn = strcspn(Buf, "#\n");
  /* length before the 1st # or return. */

  if(spn == cspn) 	/* comment line or space line. */
	return(1);
  else				/* the line has data. */	 
	return(0);		
}

/***********************************************************
 *	Skip space or comment lines and return a data line only.
 ****/
char * FindDataLine(FILE *File_Ptr)
{
  static char buf[STRLEN];	/* LW 1/11/2000. Added static. */
  
  buf[0] = '\0';
  do {	/* skip space or comment lines. */
    if(fgets(buf, 255, File_Ptr) == NULL)  {
      printf("Incomplete data\n");
      buf[0]='\0';
      break;
    }
    else
      CheckChar(buf);
  } while(CommentLine(buf));
  
  return(buf);
}

/***********************************************************
 *	Skip file version, then read number of runs.
 ****/
short ReadNumRuns(FILE* File_Ptr)
{
  char buf[STRLEN];
  short n=0;
  
  FindDataLine(File_Ptr); /* skip file version. */

  strcpy(buf, FindDataLine(File_Ptr));
  if(buf[0]=='\0') nrerror("Reading number of runs\n");
  sscanf(buf, "%hd",&n);	        
  return(n);
}

  
/***********************************************************
 *	Read the file name and the file format.
 *
 *	The file format can be either A for ASCII or B for
 *	binary.
 ****/
void ReadFnameFormat(FILE *File_Ptr, InputStruct *In_Ptr)
{
  char buf[STRLEN];

  /** read in file name and format. **/
  strcpy(buf, FindDataLine(File_Ptr));
  if(buf[0]=='\0') 
	nrerror("Reading file name and format.\n");
  sscanf(buf, "%s %c", 
	In_Ptr->out_fname, &(In_Ptr->out_fformat) );
  if(toupper(In_Ptr->out_fformat) != 'B') 
	In_Ptr->out_fformat = 'A';
}


/***********************************************************
 *	Read the number of photons.
 ****/
void ReadNumPhotons(FILE *File_Ptr, InputStruct *In_Ptr)
{
  char buf[STRLEN];

  /** read in number of photons. **/
  strcpy(buf, FindDataLine(File_Ptr));
  if(buf[0]=='\0') 
	nrerror("Reading number of photons.\n");
  sscanf(buf, "%ld", &In_Ptr->num_photons);
  if(In_Ptr->num_photons<=0) 
	nrerror("Nonpositive number of photons.\n");
}


/***********************************************************
 *	Read the members dz, dr and dt.
 ****/
void ReadDzDrDt(FILE *File_Ptr, InputStruct *In_Ptr)
{
  char buf[STRLEN];

  /** read in dz, dr and dt. **/
  strcpy(buf, FindDataLine(File_Ptr));
  if(buf[0]=='\0') nrerror("Reading dz, dr, dt.\n");
  sscanf(buf, "%lf%lf%lf", &In_Ptr->dz, &In_Ptr->dr, &In_Ptr->dt);
  if(In_Ptr->dz<=0) nrerror("Nonpositive dz.\n");
  if(In_Ptr->dr<=0) nrerror("Nonpositive dr.\n");
  if(In_Ptr->dt<=0) nrerror("Nonpositive dt.\n");
}
You are using array syntax when you don't have an array

1
2
3
4
5
6
void KillChar(size_t i, char * Str)
{
  size_t sl = strlen(Str);
  
  for(;i<sl;i++) Str[i] = Str[i+1];
}


In this function Str is only a pointer. By using the [] syntax the code will take a local copy of the data and do the work so when the function returns all the work will be lost and the array will be as if you never called the function. You need to use pointers....

1
2
3
4
5
6
7
8
9
10
11
12
void KillChar(size_t i, char * Str)
{
  size_t sl = strlen(Str);
  char *ptr = Str;
  ptr++;  // Move it to the next character
  for(;i<sl;i++)
  {
     *Str = *ptr;
     Str++;  // Increment pointers
     ptr++;
  }
}

If what you are doing is read only then it doesn't matter though not really good practice. If you are changing the data then you have to do it this way. I don't know that this is the only problem as I haven't got all your code. I've used this function as an example. I've seen a few places where you are doing this so check your code through.

One other point, in CheckChar() you are checking a char to make sure it is between 0 and 255. A char is -128 to 127, it needs to be an unsigned char for 0 to 255.


So why did it work in windows? I suspect that compiler is more forgiving.

EDIT: Actually thinking about it your 0-255 test is pointless because an unsigned char will always between those values. In a linux terminal window do

man isalpha

and that will show you a selection of calls that will probably be more useful.

Bertha
Last edited on
Honestly said, I don't agree with Bertha concerning the KillChar function. In my oppinion it works perfectly in the original version. Str is a pointer, even if you use it with ther []-operator. So it does modify the caller's data.
Actually Berthas version won't work (did you test it?), because only the pointer instead of the data pointed to is modified. So all the increments on Str will be lost when returning.

And, returning to the first question: Maybe the problem is the difference in end-of-line characters between windows (CR and LF, "\n\r") and unix (CR only). Did you convert the data file after the transfer to the linux system?

The usage of STRLEN is not fully consistent. For example, line 105 should read
if(fgets(buf, STRLEN, File_Ptr) == NULL) {
otherwise you will get trouble, if STRLEN is defined to something smaller than 255. And finally try an
printf("line >%s<, length %d", buf, strlen(buf));
after line 127 to see what you actally read.
Last edited on
There was a problem with my solution but not for the reason suggested by dwk. I needed to offset the pointers by i. It should be

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void KillChar(size_t i, char * Str)
{
  size_t sl = strlen(Str);
  char *ptr = Str + i;    // Offset pointers to starting position
  Str+= i;
  ptr++;  // Move it to the next character

  for(;i<sl;i++)
  {
     *Str = *ptr;
     Str++;  // Increment pointers
     ptr++;
  }
}

This problem has come up before http://www.cplusplus.com/forum/general/2011/ and this was the cause.

@dwk: Using the array syntax appears to be very hit and miss, some compilers handle it, some don't. You need to look again at my solution, I'm dereferencing the pointers so the underlying data is being modified.

@bmbertha you are right, I missed the asterix in your code - sorry!

Have you ever encountered a compiler, where
array[7]
and
*(array+7)
are not equivalent?
Thank you so much for your useful suggestions!
I changed the version of my input file and now it can run!

Thank you!
@dwk
Short answer yes. Long answer, only if the array is defined in a calling function and passed to the higher function as a pointer rather than an array. The higher function has read only access via the [] syntax without problem, but any changes made to members of the array using this syntax by the called function, are lost once the called function returns. It only seems to affect some compilers (not sure if it's only old versions), most don't have a problem. If I ever get around to it, I'll look up what C99 or ANSI C has to say on the subject
Hi, I am Rita, again, I have a problem.
I want to know how to improve the program running speed. Because after I run my program on Multiprocessor in our college, I found that the speed of the running is not as fast as I expected. Although it saved some time, it is still very slow.

So I am now wondering whether there are some ways to improve the running speed?


Thank you very much!
You mention multiprocessor so the obvious direction is to make your program multithreaded. If your multiprocessor box has Intel/x86 processors have a look at the TBB libraries see http://www.cplusplus.com/forum/articles/2145/ otherwise your best bet is posix threads. You haven't posted you whole program so I'll stick to general ways to identify candidates for threading.

Look for where you are processing lots of items, one after another. If they are not dependent on the result of the previous stage, you could use threading. Threading can allow multiple operations to be carried at the same time, reducing the number of execution cycles needed. The TBB documentation is probably worth reading just for explanations of the various threading models.

Hope this helps
Topic archived. No new replies allowed.