Reading strings/lines from a simple text file

Hi there, I am trying to get familiar with both C++ and the Haiku API.

One basic thing I am trying to learn is to read utf8 strings from a text file (i.e iterate and display each line).

Neither the Haiku API Book nor Darkwyn tutorial are very clear to a C++ beginner like myself. Unless mistaken, there does not seem to be a BFile.ReadString() function that will return a utf8 string and move read position to the next line.

Here is what I have so far:

#include <iostream>
#include <String.h>
#include <File.h>

int
main ()
{
	BString filePath = "/boot/home/Desktop/test";
	
	BString msgSuccess = "File successfuly opened : ";
	BString msgFailed= "Failed opening ";
	
	BString finalMessage;
	
	BFile testFile(filePath, B_READ_ONLY);
	
	if (testFile.InitCheck() != B_OK)
	{
		finalMessage = msgSuccess.Append(filePath);
		std::cout << finalMessage << std::endl;
		
		//now print file content line by line (loop until eof)
		//???
		
	}
	else
	{
		finalMessage = msgFailed.Append(filePath);
		std::cout << finalMessage << std::endl;
	}
	
	return 0;
}

What part of the Haiku API should I be using? Seek/iterate eol charaters and read the data with BDataIO.ReadExactly()?

1 Like

It seems simpler to use standard C or C++ APIs instead, for example fgets or getline:

https://en.cppreference.com/w/c/experimental/dynamic/getline

https://en.cppreference.com/w/c/io/fgets

2 Likes

@Yann64 , this would be my solution using only the Haiku API. Please note that that I´m not contradicting what @pulkomandy said above, I just wanted to offer an alternative solution. I also fixed your error checking logic because it was the wrong way around :wink:

EDIT: I removed the code from the forum post and put it into a gist because I couldn’t get it displayed correctly here in the forum. If someone could explain to me how this is done correctly, it would be greatly appreciated :wink:

2 Likes

When doing it this way, the entire file is first read into memory, then split into lines. That’s OK if you have a small file of a few kilobytes at most, otherwise, you should read the file in a loop by small chunks (which both fgets and getline will handle for you).

3 Likes

Yep, thanks for pointing that out. I should have explained it more clearly in my post.

1 Like

Indeed, thanks for that!

Use ``` before and after your code.

This is what I want to avoid as the files I want to read may be very big, so I will go the C++ standard API route. Thanks for your answer.

2 Likes

Thank you :slight_smile:

2 Likes

Also note that there is probably no nedd to append the file name to the error message string before outputting it. You should be able to just print them one after the other, like this:

std::cout << msgSuccess << filePath << std::endl;

That way you can also keep your error message string intact and won’t run into issues if you use them in more than one place in the future.

Moreover, keep in mind that your return value of your main() function is always 0, even if there is an error reading the file. It will still work fine, but it means that when running your command line program as part of a shell script for example, it won’t be easily possible for the script to detect if it succeeded or not.

2 Likes

Good point, I’ll remember that. Thanks!

1 Like