I iterate over a QByteArray which contains words. I will compare the array content with a given word (QString).
for(QByteArray::iterator it = content.begin(); it != content.end(); it++){
if(content.at(*it) == word){
...
}
}
the compiler say on line (if(content.at ..)) : invalid conversion from 'char' to 'const char*' [-fpermissive]
how can i compare the values in this case?
Chris
I iterate over an qbytearray which contains words from a file. I will compare each word with a given word.
Thanks for the clarification. In that case1 I would convert the QByteArray to QString and then split it into individual words which can then be trivially compared.
// QByteArray is implicitly convertible to QString
QString allWords = yourByteArray;
// split the string at each whitspace or newline
QStringList aWordlist = allWords.split(QRegExp("[\s\r\n]"), QString::SkipEmptyParts)
for (QStringList::iterator it=aWordlist.begin(); it != aWordlist.end(); ++it)
{
// it points to the next word in the list
if (*it == word)
{
...
}
}
1I'm assuming that you can't change the fact that you receive the file contents as byte array. Otherwise, it would probably be better to open a QFile and read the contents from there.
How can i compare the values in this case?
According to the QString documentation, QString can be compared to QByteArray without iterating. So you could simply say:
QString word("Hello");
QByteArray bytes("hi");
if (word == bytes)
{
...
}
QByteArray contains bytes. QString contains a string, that is a sequence of characters. A single byte cannot be compared to a sequence of bytes.
*it is a byte and you try to compare it to a word(i.e. a sequence of chars). I am not sure what you are trying to do but maybe you should compare content.at(*it) to the first char in the word?
I think I know what you want to do and the problem is not so much with the comparison as with the fact that you have stored your text in a QByteArray rather than a QString, or some kind of container such as a QVector, etc.
You need to look into different ways of reading in data from the QFile class. Check out the docs here:
QFile
QIODevice
I solved the problem: (QString word;)
void MainWindow::startSearching()
{
word = ui->passwordTxt->toPlainText();
string a;
fstream inputFile;
inputFile.open(fileName.data());
while(!inputFile.eof()){
inputFile >> a;
if(a == word.toStdString()){
//anything
break;
}
}
inputFile.close();
}
Related
I have a code as below
QByteArray bla("abcde");
QDataStream ds(bla.right(bla.size()-1));
QChar c;
ds>>c;
qDebug()<<c; // It prints '?' instead of 'b'
It prints out b if I change the code as
qint8 c;
ds>>c;
qDebug()<<QChar(c); // It now prints 'b'.
It's ok for a single character suppose, I have a lot of characters then I need to make a loop and cast every single of them . Please suggest a good approach.
ds>>c; equals ds>>c.unicode();, which has type ushort &. While QByteArray contains chars.
The correct way to converting QBytaArray to a sequence of QChar would be:
QByteArray bla("abcde");
QTextCodec *codec = QTextCodec::codecForLocale();
const QString string = codec->toUnicode(bla);
foreach (const QChar &c, string) {
qDebug() << c;
}
Starting from a QByteArray, I'd like to search "\n" char inside my QByteArray and join all the characters from the beginning up to "\n" and save them in a QString; after that, I'd pass to the following bytes up to the next "\n" and save these into a new QString
QByteArray MyArray= (all data from my previous process);
quint16 ByteArrayCount = MyArray.count(); // number of bytes composing MyArray
quint16 mycounter;
QString myString;
while (mycounter < ByteArrayCount)
{
if(MyArray[mycounter] != "\n")
myString.append(MyArray[mycounter]);
mycounter++;
}
This to append all bytes preceeding a new line; my problem is how to evaluate MyArray[counter], since I'm not able to check every byte when the counter increases.
Solution?
You could save yourself the trouble and simply:
QString s(myArray);
QStringList resultStrings = s.split('\n');
This will give you a list of strings split for every new line character, which is what you sound like you want to do.
Also, not to belabor the point, but you don't initialize your counter, and you really should ;)
Here is simple example of using function hello
QString str = "ooops\nhello mama\n daddy cool";
QByteArray bta;
bta.append(str);
for(quint16 index = bta.indexOf('\n');
index != -1;
index = bta.indexOf('\n', index+1)) {
/**
* Do something with index
**/
}
But according to your question there is not so clear when you say that you "not able to check every byte". If you know diapasons of available mem, you can use raw data with:
const char * ptr = MyArray.constData();
and use custom validators:
while(ptr){
if(valid(ptr) && ptr == '\n') {
/**
* do something ...
**/
}
ptr++;
}
ow and also in C/C++:
"\n" != 'n'
because "\n" - is const C string(char[2]) containing \n and EOF('\0')
and '\n' - is just simple C char;
In my app I read a string field from a file in local (not Unicode) charset.
The field is a 10 bytes, the remainder is filled with zeros if the string < 10 bytes.
char str ="STRING\0\0\0\0"; // that was read from file
QByteArray fieldArr(str,10); // fieldArr now is STRING\000\000\000\000
fieldArr = fieldArr.trimmed() // from some reason array still containts zeros
QTextCodec *textCodec = QTextCodec::codecForLocale();
QString field = textCodec->ToUnicode(fieldArr).trimmed(); // also not removes zeros
So my question - how can I remove trailing zeros from a string?
P.S. I see zeros in "Local and Expressions" window while debuging
I'm going to assume that str is supposed to be char const * instead of char.
Just don't go over QByteArray -- QTextCodec can handle a C string, and it ends with the first null byte:
QString field = textCodec->toUnicode(str).trimmed();
Addendum: Since the string might not be zero-terminated, adding storage for a null byte to the end seems to be impossible, and making a copy to prepare for making a copy seems wasteful, I suggest calculating the length ourselves and using the toUnicode overload that accepts a char pointer and a length.
std::find is good for this, since it returns the ending iterator of the given range if an element is not found in it. This makes special-case handling unnecessary:
QString field = textCodec->toUnicode(str, std::find(str, str + 10, '\0') - str).trimmed();
Does this work for you?
#include <QDebug>
#include <QByteArray>
int main()
{
char str[] = "STRING\0\0\0\0";
auto ba = QByteArray::fromRawData(str, 10);
qDebug() << ba.trimmed(); // does not work
qDebug() << ba.simplified(); // does not work
auto index = ba.indexOf('\0');
if (index != -1)
ba.truncate(index);
qDebug() << ba;
return 0;
}
Using fromRawData() saves an extra copy. Make sure that the str
stays around until you delete the ba.
indexOf() is safe even if you have filled the whole str since
QByteArray knows you only have 10 bytes you can safely access. It
won't touch 11th or later. No buffer overrun.
Once you removed extra \0, it's trivial to convert to a QString.
You can truncate the string after the first \0:
char * str = "STRING\0\0\0\0"; // Assuming that was read from file
QString field(str); // field == "STRING\0\0\0\0"
field.truncate(field.indexOf(QChar::Null)); // field == "STRING" (without '\0' at the end)
I would do it like this:
char* str = "STRING\0\0\0\0";
QByteArray fieldArr;
for(quint32 i = 0; i < 10; i++)
{
if(str[i] != '\0')
{
fieldArr.append(str[i]);
}
}
QString can be constructed from a char array pointer using fromLocal8Bit. The codec is chosen the same way you do manually in your code.
You need to set the length manually to 10 since you say you have no guarantee that an terminating null byte is present.
Then you can use remove() to get rid of all null bytes. Caution: STRI\0\0\0\0NG will also result in STRING but you said that this does not happen.
char *str = "STRING\0\0\0\0"; // that was read from file
QString field = QString::fromLocal8Bit(str, 10);
field.remove(QChar::Null);
I'm reading data from a file and trying to display the raw data as 2 digit hex strings.
I'm using the Qt framework, specifically the QTextEdit.
I've tried a bunch of different approaches and have almost accomplished what I want it to do, however it has some unexpected errors I don't know anything about.
Currently this is my implementation:
1) Read in the data:
ifstream file (filePath, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
memblock = new char [size+1];
file.seekg(0, ios::beg);
file.read(memblock, size);
file.close();
}
2) Create a single QString that will be used (because QTextEdit requires a QString):
QString s;
3) Loop through the array appending each successive character to the QString s.
int count = 0;
for(i=0;i<size;i++)
{
count++;;
s.append(QString::number(memblock[i], 16).toUpper());
s.append("\t");
if (count == 16)
{
s.append("\n");
count -= 16;
}
}
Now this works fine, except when it reaches a character FF, it appears as FFFFFFFFFFFFFFFF
So my main questions are:
Why do only the 'FF' characters appear as 'FFFFFFFFFFFFFFFF' instead?
Is there a way to convert the char data to base 16 strings without using QString::number?
I want this implementation to be as fast as possible, so if something like sprintf could work, please let me know, as I would guess that might be faster that QString::number.
QString can't be used for binary data. You should use QByteArray instead. It can be easily created from char* buffer and can be easily converted to hex string using toHex.
QByteArray array(memblock, size);
textEdit->setText(QString(array.toHex()));
QString::number doesn't have an overload that takes a char, so your input is being promoted to an int; consequently you're seeing the effects of sign extension. You should be seeing similar behavior for any input greater than 0x7F.
Try casting the data prior to calling the function.
s.append(QString::number(static_cast<unsigned char>(memblock[i]), 16).toUpper());
I am relatively new to c++ programming and I have hit one of my first major snags in all of this..
I am trying to figure out how to read a value/character from a generic ".txt" file that is on notepad. With that comparison I want to determine whether or not to read that entire line, but I can't seem to just read the single one or two digit number, I got it to read the whole line using { 'buffername'.getline(variable, size) } but when I try to change the 'size' to a specific number it gives me a comparison error saying that its invalid to switch to 'int' or 'char' (depending on how I declare the variable).
Any help is appreciated.
Thanks
int length = 2;
char * buffer;
ifstream is;
is.open ("test.txt", ios::binary );
// allocate memory:
buffer = new char [length];
// read 2 char
is.read (buffer,length);
//Compare the character and decide
delete[] buffer;
return 0;
You'll want to use an ifstream to get the value (ref 1).
Something like the following should work. Here I use a word of type std::string, but you can replace that with other types to read them (ie: int, double, etc...).
std::ifstream f("somefile.txt");
std::string word;
std::string line;
if(f >> word){
if(<the comparison>){
line = f.getline();
}
}
Here's an extended example of how to use the ifstream
First of all, for performance reasons it is a bad idea to read 1 byte at a time.
I suggest this alternative:
You would be better off reading in the whole line, and then using character array.
char variable[1000];
read your line in from the file into variable.
if (variable[1]=='c') { printf("Byte 2 (remember 0 offset) is compared for the letter c";}
getting a 2 digit #
number=((variable[3]-48)*10)+(variable[4]-48);
You have to subtract 48 because in ASCII the number 0 is 48.