Writing Text Via fwrite

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Writing Text Via fwrite

Post by Baker »

There are at 3 different ways "newlines" are handled by different operating systems.

The Windows "carriage return + line feed" way (MH says this was due to dot matrix printers or something like that) characters 13 + 10
The Unix "newline" way character 10
And maybe (I hope not) a stupid Mac way character 13 only .... oh thank god ... OS X is "Unix", it was old school "Mac OS" that was weirded up.

Ok ... anyway ... here is the question.

Isn't fopen (fileToWrite, "wb") better to use to write text than fopen (fileToWrite, "w")?

Because by specifying binary, it takes away any discretional crapola the operating system might decide is "best".

Then again, notepad.exe seems to hate files without CR in them. I bet most decent text editors don't care, but still that's the Window standard :(
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: Writing Text Via fwrite

Post by gnounc »

dont take any cues from notepad.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Writing Text Via fwrite

Post by Spike »

if its really a text file, and not going to be given to an (old) mac, open with no b and use only \n. if its binary (or you don't actually know) use b and be prepared to accept any of '\r' '\n' '\r\n'.
if you always say binary then there's no issues sending the file between different systems, but like you say notepad (and a few mac/dos programs etc) can't cope - but it is at least marginally smaller!

personally I wouldn't care about mac, from what I gather the recent versions all understand \n just fine. just find the \n and be prepared to strip any preceeding \r.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Writing Text Via fwrite

Post by Baker »

Spike wrote:if its really a text file, and not going to be given to an (old) mac, open with no b and use only \n. if its binary (or you don't actually know) use b and be prepared to accept any of '\r' '\n' '\r\n'.
if you always say binary then there's no issues sending the file between different systems, but like you say notepad (and a few mac/dos programs etc) can't cope - but it is at least marginally smaller!

personally I wouldn't care about mac, from what I gather the recent versions all understand \n just fine. just find the \n and be prepared to strip any preceeding \r.
I'm resisting the obvious thing I need to do. Which is modify this function I wrote ... which is hardwired to char at least a couple of functions deep.

Or write a search and replace text function. Which I really need to do.

Code: Select all

// What about carriage returns?
linetext_t** String_NewLine_Split_ListAlloc (const char* myString, parseoption parseOptions )
{
	const char	delimiter		= '\n';
	const int	maxParms		= String_Count_Params (myString, delimiter) + 1;
	linetext_t	Params[maxParms];
	int			numParams		= 0;
	int			emptyLineCount	= 0;

	// Obtain list of delimiter indices
	size_t**	delimPosList	= String_Delimitors_Indices_ListAlloc (myString, delimiter);
	const int	numDelimPosList	= List_Count (delimPosList);

	const size_t startOfString	= 0;
	const size_t endOfString	= strlen(myString) - 1;

	for (int i = 0; i <= numDelimPosList; i ++)
	{
		// Start: First instance use 0 else use previous delimitor position + 1
		// Start: Last instance use 0 else use current delimitor position  1
		const size_t start = (i == 0              ) ? startOfString : *delimPosList[i-1] + 1;
		const size_t end   = (i == numDelimPosList) ? endOfString   : *delimPosList[i]   - 1;

		String_Copy_Range (myString, start, end, Params[numParams].line,   sizeof(Params[numParams].line)   );

		if (parseOptions & PARSE_REMOVE_TRAILING_SPACES)
			String_Edit_Remove_Trailing_Spaces(Params[numParams].line);

		if (Params[numParams].line[0] == 0) emptyLineCount ++;

		printf ("Params[%i] line: '%s' \n", numParams, Params[numParams].line);
		numParams ++;
	}

	List_free (delimPosList);

	if (emptyLineCount > 0 && (parseOptions & PARSE_IGNORE_EMPTY_LINES) )
	{
		// Ok this is special
		int newCount = maxParms - emptyLineCount;
		linetext_t	filteredParams[newCount];
		int			numFilteredParams = 0;
		for (int i = 0; i < numParams; i ++)
			if (Params[i].line[0] != 0)
			{
				// We are adding only non-blank lines
				StringLCopy(filteredParams[numFilteredParams].line, Params[i].line);
				numFilteredParams ++;
			}

		ReturnList_Alloc (linetext_t**, filteredParams);
		// We're gone.  Other array blinks out of existence instead of being allocated
	}


	ReturnList_Alloc (linetext_t**, Params);
}
Realistically the above function doesn't stand a chance in hell in compiling in Visual Studio anyway without some significant rewrites. I've discovered even gcc really dislikes some of the stuff I can get away with doing using Clang/LLVM and I swear MSVC6 didn't mind some things that VS 2008 is not liking.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
mankrip
Posts: 924
Joined: Fri Jul 04, 2008 3:02 am

Re: Writing Text Via fwrite

Post by mankrip »

If disk space is not a concern (like, you're not trying to create savegames for a device with a ridiculously small amount of space such as a VMU), use the Windows standard.

The Unix standard is better, I agree, but alienating Windows users because of that is ridiculous. I facepalm every time I see Windows programs being released with readme files that follows the Unix standard.

Also, I have never encountered any Linux programs that had problems reading text files created in the Windows standard.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: Writing Text Via fwrite

Post by mh »

Notepad never pretended to be a serious text editor - it's just an edit control with a coupla menus and other bits slapped on. It's only in the Unix world where the text editor that comes with the OS is considered an important tool. In the Windows world this is not seen as something dramatic or dreadful.

If you're worried about disk space usage from an extra byte per line in Quake plain text files that are written, then you've probably got bigger problems.

Read this: http://blogs.msdn.com/b/oldnewthing/arc ... 91899.aspx

This kind of crap is one reason why binary files are so much more better than text files. Yes, text files have advantages in some situations, but binary files just make this pointless distinction go away.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Writing Text Via fwrite

Post by Baker »

mh wrote:Notepad never pretended to be a serious text editor - it's just an edit control with a coupla menus and other bits slapped on.
I'm more thinking about what happens when someone "normal" opens one of these files. If it all the lines are mashed together, that doesn't reflect well from the perception of some average joe.
mh wrote:If you're worried about disk space usage from an extra byte per line in Quake plain text files that are written, then you've probably got bigger problems.
Ideally, I'd like to there to be "one right way do stuff".

But since I do care what someone using NotePad opening the file perceives, I guess not.

Not really a big deal since I discovered that that silly character 13 Mac OS thing is like 1990s Macs. But I wasn't sure since old Fruitz of Dojo Quake had all kinds of crap in the source dealing with character 13 and newlines --- but they probably did that because back in 2002 someone with real MacQuake install might encounter something.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Writing Text Via fwrite

Post by frag.machine »

For text files I always used

Code: Select all

 FILE *f = fopen ("blah.txt", "wt"); // truncate if exists and writes as text
or

Code: Select all

 FILE *f = fopen ("blah.txt", "at"); // appends as text to the end if the file already exists
or

Code: Select all

 FILE *f = fopen ("blah.txt", "rt"); // treats the file as text and handles the '\r' '\n' mess according the OS preferences
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Post Reply