Finding a specific character in a file in Qt - qt

How can i find a specific character in a QFile which has a text in it?
for example i have ' $5000 ' written somewhere in my file. in want to find the "$" sign so i will realize that I've reached the number.
I tried using QString QTextStream::read(qint64 maxlen) by putting 1 as the maxlen :
QFile myfile("myfile.txt");
myfile.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream myfile_stream(&myfile);
while(! myfile_stream.atEnd())
{
if( myfile_stream.read(1) == '$')
{
qDebug()<<"found";
break;
}
}
and i get "error: invalid conversion from 'char' to 'const char* "
i also tried using the operator[] but apparently it can't be used for files.

Read in a line at a time and search the text that you've read in
QTextStream stream(&myFile);
QString line;
do
{
line = stream.readLine();
if(line.contains("$"))
{
qDebug()<<"found";
break;
}
} while (!line.isNull());

The error message you've posted doesn't match the issue in your code. Possibly the error was caused by something else.
QTextStream::read returns QString. You can't compare QString and const char* directly, but operator[] can help:
QString s = stream.read(1);
if (s.count() == 1) {
if (s[0] == '$') {
//...
}
}
However reading a file by too small pieces will be very slow. If your file is small enough, you can read it all at once:
QString s = stream.readAll();
int index = s.indexOf('$');
If your file is large, it's better to read file by small chunks (1024 bytes for example) and calculate the index of found character using indexOf result and count of already read chunks.

a single char could be read with
QTextStream myfile_stream(&myfile);
QChar c;
while (!myfile_stream.atEnd())
myfile_stream >> c;
if (c == '$') {
...
}

myfile_stream.read(1) - this is not good practice, you should not read from file one byte at a time. Either read the entire file, or buffered/line by line if there is a risk for the file to be too big to fit in memory.
The error you get is because you compare a QString for equality with a character literal - needless to say that is not going to work as expected. A string is a string even if there is only one character in it. As advised - use either the [] operator or better off for reading - QString::at() const which is guaranteed to create no extra copy. You don't use it on the QFile, nor on the QTextStream, but on the QString that is returned from the read() method of the text stream targeted at the file.
Once you have the text in memory, you can either use the regular QString methods like indexOf() to search for the index of a contained character.

in want to find the "$" sign so i will realize that I've reached the
number.
It sounds to me that you're searching for the '$' symbol because you're more interested in the dollar value that follows it. In this case, I suggest reading the files line by line and running them through a QRegExp to extract any values you're looking for.
QRegExp dollarFind("\\$(\\d+)");
while(!myfile_stream.atEnd()){
QString line = myfile_stream.readLine();
if (dollarFind.exactMatch(line)){
QStringList dollars = dollarFind.capturedTexts();
qDebug() << "Dollar values found: " << dollars.join(", ");
}
}

Related

QRegExp and Null Character in Qt

i want search in a binary file with regular expression.
my search is successful in Text files, but not match in binary file, because QRegExp in function indexIn stop search when meet the NULL Character (chr(0)).
what can i do to solve this problem?
QString can contain null characters, it's just its constructors that are inconsistent...
QString::fromUtf8(const char *str, int size = -1) uses the given size, while QString::fromUtf8(const QByteArray &str) forces a strlen instead of using the bytearray size. See for yourself Qt code.
QRegExp also supports null characters:
QString s(QChar(0));
QRegExp re(s);
qDebug() << re.indexIn(s); // will print 0, not -1

How to open a file in Qt-method but read it use C-language function?

I know Qt has a lot of good methods for reading file.But in my work , I have to open a file by using Qt and get a pointer pointing to the start address of the file.So how to do that?
Here is my codes:
char *buffer;
if(file.open(QIODevice::ReadOnly))
{
QByteArray dataArray=file.readAll();
buffer=dataArray.data();
}
char test[1024];
for(int i=0;i<1024;i++)
{
test[i]=*buffer;
buffer++;
}
I use QByteArray QIODevice::​readAll()to read all available data from the device, and returns it as a byte array.
Then I use char * QByteArray::​data() to set my pointer buffer.
But when I try to read the data by a for loop,my Qt debugger throw me an error:read access violation,so how would this happen?
BTW , the file to be read is very big so I can't use a buffer to read them all once. Instead , I have to do as what I did here. When I read a 7kb-sizes-file ,my codes runs well. When I read a 700kb-sizes-file , here comes the problem.
The reason you are getting access violation is that dataArray is declared inside if code block and goes out of scope. You want to declare the dataArray outside of that block, eg:
QByteArray dataArray;
if(file.open(QIODevice::ReadOnly))
{
dataArray = file.readAll();
}
else
{
// give error
}
char *buffer = dataArray.data();
char test[1024];
for(int i = 0; i < 1024; i++)
{
test[i] = *buffer;
buffer++;
}
There are other potential problems in your code though:
First, what if the size of data read from the file is less than 1024? Then you will be reading past the end of the buffer (more access violations).
Second, what if the file is really big? Reading all that data at once may cause swapping/paging.

QTestLib results different from program output

I have some simple code that reverses a QString.
const QString reverse_qstring(const QString& str_in)
{
QString out;
Q_FOREACH(const QChar c, str_in) {
out.push_front(c);
}
return out;
}
When I input text from the command line with non-ASCII characters, things go as expected:
"¿como estás?" : "?sátse omoc¿"
However, when I make the following unit test (Using QTestLib):
QCOMPARE(reverse_qstring(QString("¿como estás?")), QString("?sátse omoc¿"));
I get:
FAIL! : program::test_qstring() Compared values are not the same
Actual (reverse_qstring(QString("??como est??s?"))): ?s??tse omoc??
Expected (QString("?s??tse omoc??")): ?s??tse omoc??
Any ideas?
I think you can set the codec for Utf8: http://doc.qt.io/qt-4.8/qtextcodec.html#setCodecForCStrings
Or you can use this instead: QString::fromUtf8("?sátse omoc¿")

vector data check

hi a have a function that reads from a text file line by line each line I do some operations on it substitute a string..etc
then I push_back that line into a vector
this is my class in Parser.h
class Parser
{// start class
public:
vector<const char*> patterns;
Parser();
~Parser();
void RuleParser(const char *TextFileName); // this is the function that takes the file name
private:
};// end class
segment from function RuleParser
std::ifstream ifs(TextFileName);
while (!ifs.eof())
{
.
.modification code
.
patterns.push_back((buildString).c_str()); //buildString is the modified line
cout << buildString << endl;
}
but when I try to check out if the data in the vector is correct it output totally different data.
I even put a cout after the push_back to check it's integrty but I found buildString is correct... thats the data each time being pushed ... what I am doing wrong.
here is the loop I use to see if my data correct.
for (int i = 0;i < patterns.size() ;i++)
{
cout << patterns.at(i) << endl;
}
Well patterns is the collection of pointers so you end up push_back'ing a pointer to the same buildString in each iteration of the loop, instead of push_back'ing the string contents. Then when buildString changes in next iteration of the loop, the pointer becomes invalid but it still remains in patterns - not good
I suggest you declare patterns as:
vector<std::string> patterns;
This way when you do:
patterns.push_back(buildString.c_str())
the contents of the string will be copied instead of the pointer, and remain valid througout.

read a text file to QStringList

I have a text file. I need to read it to a QStringList. there are no line seperators. I mean each line in the text file is in a new line. So is there anyway i can do this?
I assume that every line should be a separate string in the list. Use QTextStream::readLine() in a cycle and on each step append the returned value to the QStringList. Like this:
QStringList stringList;
QFile textFile;
//... (open the file for reading, etc.)
QTextStream textStream(&textFile);
while (true)
{
QString line = textStream.readLine();
if (line.isNull())
break;
else
stringList.append(line);
}
QFile TextFile;
//Open file for reading
QStringList SL;
while(!TextFile.atEnd())
SL.append(TextFile.readLine());
If the file isn't too big, read the whole content into a QString and then split() it into a QStringList.
I like using the QRegExp version to handle linefeed from different platforms:
QStringList sList = s.split(QRegExp("(\\r\\n)|(\\n\\r)|\\r|\\n"), QString::SkipEmptyParts);
I like my code to be fully indented/paranthesized with obvious variable names (they may take longer to type but are much easier to debug) so would do the following (but changing "myTextFile" and "myStringList" to more sensible names, such as "employeeListTextFile")
QFile myTextFile;
QStringList myStringList;
if (!myTextFile.open(QIODevice::ReadOnly))
{
QMessageBox::information(0, "Error opening file", myTextFile.errorString());
}
else
{
while(!myTextFile.atEnd())
{
myStringList.append(myTextFile.readLine());
}
myTextFile.close();
}
The below code reads the file
QFile File("/file_path");
if(!File.open(QIODevice::ReadOnly));
{
qDebug("Error");
}
QTextStream in(&File);
while(!in.atEnd())
{
qDebug()<<ReadAll;
ReadAll=in.readAll();
}
File.close();
Now the file is closed, now split the new line i.e \n here \r is carriage return
List= ReadAll.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);

Resources