?
Solved

fread not reading all the characters all the time...

Posted on 2010-01-11
17
Medium Priority
?
318 Views
Last Modified: 2013-12-14
i am trying to read in a config.txt file to set the config options for my program.  the config file uses return characters to delimit the different settings.  the first line to read is simply an ip address with a colon and a port number...half of the time when i call fread it works fine...half of the time it skips the first 4 digits (ie. 67.90.xx.xx:50xx  vs. 0.xx.xx:50xx).  code and config file are listed below...

if i run this 10 times in a row about 50/50 on how it reads in the config.txt file
my code***

char *configfilename = "C:\\Users\\Administrator\\Desktop\\config.txt";
	char configbuffer[100]= "";
	char *domain;
	char domainuri[20] = "sip:";
	char *user;
	char *pass;
	char *copath;
	char sipstring[80] = "sip:";	
				
	configfile = fopen(configfilename, "r+");
	fread(configbuffer, 1, 98, configfile);
	
	//configbuffer[99] = 0;
	domain = strtok(configbuffer, "\n");
	user = strtok(NULL, "\n");
	pass = strtok(NULL, "\n");
	copath = strtok(NULL, "\n");
        fclose(configfile);


my config file***

67.90.xx.xx:50xx
N38N87NXX16N3N1
BJD892JXXDK93JSL9DJ4
C:\\co\\*.co

Open in new window

0
Comment
Question by:csummer
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 5
17 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 26287222
Hi csummer,

That's an odd way to read a config file, but it should work just fine.

A much more versatile way is to read one line at a time.  That makes managing the file much easier if the file ever changes.


But as to the code that you've posted, I see nothing that should cause the randomness that you describe.


Kent
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287286
>> but it should work just fine.

Not necessarily. If the total size of the file (including newlines) is longer than 98 bytes, you won't read enough. Since you don't null-terminate the read data, strtok might not work correctly either.

Granted, this should not give the behavior the author describes at the beginning of the file, assuming that the code that was posted is representative.

But they're problems that should be addressed nevertheless (preferably by reading the data as a text file, line by line as Kdo already suggested).
0
 

Author Comment

by:csummer
ID: 26287321
me either...but i assure you its happening...

we are mostly a .net/java shop and i showed our other programmers and they are just as puzzled as i am regarding this...i hoped i was just doing something stupid or silly...

the reason why i didnt do read line was because fread reads in the whole file in one operation where as fread only does one line at a time...sure its not gonna be a large difference in this situation but its old coding habit...

on a side note which may or may not be related...when i am reading and working with strings...sometimes in my debugger some of my strings appear as asian characters...even though it will resolve to the proper english characters when called.  i was wondering if i may have the wrong character set or so chosen for this project...but i have no idea how that got messed up...i rarely edit the detailed config settings in visual studio...

anybody else have any ideas??
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.

 
LVL 46

Expert Comment

by:Kent Olsen
ID: 26287359
Hi csummer,

Another thought.  :)  (They come randomly some times....)

Based on the path name in your code, you're running on a Windows system.  If your configuration file is created as a Windows or DOS file, lines are terminated by a carriage return AND line feed.  (If it's a unix formatted file, only the line feed character is used.)

You're calling strtok() to separate the tokens.  But scanning only for '\n', each string will likely be terminated by a '\r' character.  That may cause an issue when you go to display the value!

Replace the string "\n" with "\r\n" in the call to strtok.  That will cause strtok to split the tokens at either a carriage return or line feed, and skip consecutive CR or LF characters so that neither will appear in your string.


Good Luck,
Kent
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287376
>> the reason why i didnt do read line was because fread reads in the whole file in one operation where as fread only does one line at a time...sure its not gonna be a large difference in this situation but its old coding habit...

If you're doing this for reason of performance - don't bother. Let the underlying system deal with file buffering ;) It does a pretty good job most if the time.

>> but i assure you its happening...

Could you show the exact and complete code ? Or if you can't provide that, at least a fully compilable sample code that exhibits the same problem ?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287393
@Kdo - that wouldn't give the issue on the first line of the file though;
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 26287417
>> the reason why i didnt do read line was because fread reads in the whole file in one operation where as fread only does one line at a time...sure its not gonna be a large difference in this situation but its old coding habit...

C will block and buffer the input so that each call to fgets() moves the line from the buffer until the buffer is exhausted and another physical read is necessary.  fgets() does not automatically read from disk for every call.


0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287456
>> sometimes in my debugger some of my strings appear as asian characters...

Are you reading the 4 strings read from the file with your debugger ?

If so, try printing them out to standard output instead to see if they contain the correct data. Place this after the fclose call :
fprintf(stdout, "domain : %s\n", domain);
fprintf(stdout, "user : %s\n", user);
fprintf(stdout, "pass : %s\n", pass);
fprintf(stdout, "copath : %s\n", copath);

Open in new window

0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 26287461
>> that wouldn't give the issue on the first line of the file though;

Maybe, maybe not.  I'd like to see the strings printed as hex instead of ASCII.  It would be interesting to see exactly what the strings really contain.

If the strings contain what csummer is actually seeing, it suggests that the error doesn't really lie with this code, but that the program is already corrupt and this is just a symptom....

Kent
0
 

Author Comment

by:csummer
ID: 26287511
the strtok was working fine before...its funny cause when it compiles and works...i am then able to run the exe and it always seems to work...but every other time it misses the first 4 characters when reading in the config.txt file...

this is at the top of my code ...perhaps im using the wrong libraries???
#include <stdlib.h>
#include <windows.h>

im not entirely sure what other code you would need to see...realistically as soon as it opens the file and freads its already wrong...the code compiles and works (if incorrectly)...

im gonna try to use the fgets instead to see how that does...but this is really weird behavior...

thanks...
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 26287553

Do you always read the same configuration file?

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287580
>> im not entirely sure what other code you would need to see...

If what you posted is exactly what you use, with nothing left out, nothing modified, and nothing added, then that's ok.

Do try to place the fprintf lines I mentioned earlier after the fclose call to see if it's a problem with your debugger not being able to read the variables correctly.
0
 

Author Comment

by:csummer
ID: 26287776
yes i always use the same config.txt file...

so i changed the code in order to output the config buffer as shown in the code below...right after the fread i use "puts(configbuffer);" and it printed out the whole file correctly...but when i copy and paste from the locals window (while debugging) configbuffer looks like this

"-            configbuffer      0x001cfbd4 "0.16.6:5070
E386873161301
9OG7VWVO4PWPMEH3FOUR
C:\\co\\*.co"      char [100]
"

configbuffer[0] = 48'0'
configbuffer[1] = 46'.'
configbuffer[2] = 49'1'
etc...

why would puts(configbuffer) print out to the console correctly when the buffer file seems to be missing the first 4 characters...

it may be possible to get around this behavior...i just wish i new why it was behaving this way...
0
 

Author Comment

by:csummer
ID: 26287794
i forgot to add how i changed the code... here it is
FILE *configfile;
	//char *configfilename = "c:\\Program Files\\PCDispatch\\callout3\\config.txt";
	char *configfilename = "C:\\Users\\Administrator\\Desktop\\config.txt";
	char configbuffer[100]= "";
	char *domain;
	char domainuri[20] = "sip:";
	char *user;
	char *pass;
	char *copath;
	char sipstring[80] = "sip:";
	
				
	configfile = fopen(configfilename, "r+");
	fread(configbuffer, 1, 95, configfile);
	puts(configbuffer);
	
	//configbuffer[99] = 0;
	domain = strtok(configbuffer, "\n");
	user = strtok(NULL, "\n");
	pass = strtok(NULL, "\n");
	copath = strtok(NULL, "\n");

	fclose(configfile);

Open in new window

0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1000 total points
ID: 26287831
Debuggers aren't always able to retrieve the information correctly. Especially not if the project settings haven't been set correctly. You are compiling the debug version, aren't you ? And you don't strip any debugging symbols out ?

Either way, if the puts or fprintf statements print the right values (did you try adding the 4 I mentioned earlier ?), then the code is working just fine. It's just your debugger that has an issue ...
0
 

Author Comment

by:csummer
ID: 26287983
ok....i have been struggling to get this program to compile correctly with the libraries i am using...i just realized that i compiled a release version to test out and i never changed my settings back from release to debug...when i found a bug i just started debugging in release mode and from what i understand now, because the debugging mode wasnt set correctly my debugger was showing the wrong info...

i changed it back to debug mode and so far 10/10 it has shown the debugging info correctly...this means that the error i thought i had lies somewhere else and now that i know that the debugging tools can be incorrect...im planning on outputting any data im curious about to the console...

thanks for the help...
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 26287991
No worries :)
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

765 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question