Don't laugh, but what on earth am i missing? - nsstring

OK, I probably have no business trying to learn an OOP and I'm having trouble with the simplest little first program. I am getting a message that my implementation is incomplete (I commented the line that is giving 4 errors below). What is wrong? It wants a type specifier among other things, but don't I give it one with NSString? I do notice that NSString doesn't change color to a green type color in XCODE in the implementation like it does in the interface.
ALSO, why do we need to declare the method in the interface and type the exact same thing in the implementation? that is, why the need to type the startDrinking: (NSString*) newBeverage in both?
#import <Foundation/Foundation.h>
#interface Drinks : NSObject {
NSString *beverage;
}
- (void) startDrinking: (NSString*) newBeverage; // setter
- (void) printDrink;
#end
#implementation Drinks
{
//THIS NEXT LINE IS WHERE I GET 4 ERRORS
- (void) startDrinking: (NSString *) newBeverage {
beverage = [[NSString alloc]initwithString:newBeverage]
}
-(void) printDrink {
NSLog(#"How is your", beverage);
}
}
#end
int main (int argc, const char * argv[]) {
Drinks *beverage = [[Drinks alloc] init];
[beverage startDrinking:#"Lemonade"];
return 0;
}

Your question is too chatty.
You missed a semi-colon in line beverage = [[NSString alloc]initwithString:newBeverage]
The line should be :
beverage = newBeverage;
and the NSLog line should be:
NSLog(#"How is your %#", beverage);
and for the declaration of method signature in header, it is followed by C and C++ . You can think of, the Compiler needs to know which functions are available first.

Your mistake is the { right below #implementation Drinks.
That's why the alignment is messed up too.
In general, if you can't find an error on the line it is reported on, just check any extraneous or missing parenthesis, brackets or braces.
The weird alignment is another clue to this.
Hope this helps. Also, like some other said, it helps if your subject is more meaningful. Not just for yourself, but also for any others that might be having a similar problem

Related

QTextLayout / QTextLine support grouping of several-characters so it acts as one character for the cursor

Is it possible for QTextLayout to render several characters, but to process/handle it as one character. For example rendering a code point like: [U+202e], and when moving the caret/calculating positions, it is treated as one character.
Edited:
Please check this following issue, were I explain what I'm trying to do. It for the edbee Qt component. It's using QTextLayout for line rendering.
https://github.com/edbee/edbee-lib/issues/127
Possibly it isn't possible with QTextLayout, the documentation is quite limited.
According to Qt docs:
"The class has a rather low level API and unless you intend to implement your own text rendering for some specialized widget, you probably won't need to use it directly." - https://doc.qt.io/qt-5/qtextlayout.html#details
You should probably use a QLineEdit or a QTextEdit (each has a method called setReadOnly(bool)).
Before answering the question, I will point out that the CursorMode enum (https://doc.qt.io/qt-5/qtextlayout.html#CursorMode-enum) seems very promising for this problem, but to me, the documentation isn't clear on how to use it or set it.
Now to answer your question in regards to QLineEdit or QTextEdit, it's a bit complicated, but it's the same for QLineEdit and QTextEdit, so lets look at QTextEdit.
Firstly, mouse clicks: QTextEdit has a signal called cursorPositionChanged(), which will be helpful here. You'll want to connect that to a custom slot, which can make use of the function moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor) (https://doc.qt.io/qt-5/qtextedit.html#moveCursor). Notice that there are very helpful enumeration values for you here in QTextCursor::MoveOperation regarding word hopping (https://doc.qt.io/qt-5/qtextcursor.html#MoveOperation-enum). How do we put all of this together? Well, probably the right way to do it is to determine the width of the chars to the left of the cursor's position and the width of the chars to the right of the cursor's position when the cursorPositionChanged() signal is emitted and go to the side of the word that has less width. However, I'm not sure how to do that. At this point I'd settle with checking the number of chars to the left and right and going to the side with less.
Secondly, keyboard presses: This goes a bit out of my knowledge, but almost everything drawable and iteractable inherits from QWidget. Take a look at https://doc.qt.io/qt-5/qwidget.html#keyPressEvent and it's possible that overriding that in your own implementation of QTextEdit is necessary to get the left arrow and right arrow keypresses to jump words (once you get that part it's pretty easy, just use the same function as last section for moving the cursor, or in the case of QLineEdit, cursorWordForward()/cursorWordBackward()).
All this being said, I've so far been assuming that you're not deleting anything or selecting anything. Selection can be a real pain depending on if you allow multiple selections, but the functions are all there in the documentation to implement those things.
Example of mouse click impl:
myclass.hpp
#include <QTextEdit>
#include <QTextCursor>
#include <QObject>
#include <QString>
int distance_to_word_beginning_or_end(const QString &str, int index, bool beginning);
class MyClass {
MyClass();
~MyClass();
private:
QTextEdit *text_edit;
public slots:
void text_edit_changed_cursor_location();
};
myclass.cpp
#include "myclass.hpp"
int distance_to_word_beginning_or_end(const QString &str, int index, bool beginning)
{
// return the distance from the beginning or end of the word from the index given
int inc_or_dec = (beginning) ? -1 : 1;
int distance = 0;
while (index >= 0 && index < str.length())
{
if (str.at(index) == ' ' || str.at(index) == '\n' || str.at(index) == '\t')
{
return distance;
}
distance++;
index += inc_or_dec;
}
return --distance;
}
MyClass::MyClass()
{
text_edit = new QTextEdit();
QObject::connect(text_edit, &QTextEdit::cursorPositionChanged, this, &MyClass::text_edit_changed_cursor_location);
}
MyClass::~MyClass()
{
delete text_edit;
}
void MyClass::text_edit_changed_cursor_location()
{
QString text_edit_string = text_edit->text();
QTextCursor text_edit_cursor = text_edit->textCursor();
auto current_position = text_edit_cursor.position();
QTextCursor new_text_cursor;
int distance_to_beginning = distance_to_word_beginning_or_end(text_edit_string, current_position, true);
int distance_to_end = distance_to_word_beginning_or_end(text_edit_string, current_position, false);
auto movement_type;
if (distance_to_beginning > distance_to_end)
{
new_text_cursor.setPosition(current_position + distance_to_end);
} else {
new_text_cursor.setPosition(current_position - distance_to_beginning);
}
text_edit->setTextCursor(new_text_cursor);
}

Rf_error and Rf_warning definitions

Where can I find the definitions for these two functions. Grepping for their name brings only declarations but I can't find their implementation in the source code.
Presumably you are looking for the C code function definitions. What I typically do when looking for the definitions is search across all files for the function name without the Rf_ but with the return type. For example, for Rf_error, I would search for void error. In this case you pretty quickly get (from src/main/errors.c#758, for R version 3.2.2):
void error(const char *format, ...)
{
char buf[BUFSIZE];
RCNTXT *c = R_GlobalContext;
va_list(ap);
va_start(ap, format);
Rvsnprintf(buf, min(BUFSIZE, R_WarnLength), format, ap);
va_end(ap);
/* This can be called before R_GlobalContext is defined, so... */
/* If profiling is on, this can be a CTXT_BUILTIN */
if (c && (c->callflag & CTXT_BUILTIN)) c = c->nextcontext;
errorcall(c ? c->call : R_NilValue, "%s", buf);
}
Rf_warning is defined at line 262 of the same file.
Note the following lines in src/include/R_ext/Error.h
#ifndef R_NO_REMAP
#define error Rf_error
#define warning Rf_warning
#endif
R_NO_REMAP is usually not defined, so that means the macro error expands to Rf_error. So, in files that include Error.h, instances of error will be replaced with Rf_error by the preprocessor.
So you need to search for the function with the same return type and arguments. As BrodieG notes in his answer, the functions also usually (always?) have the same name, but without the Rf_ prefix.
Thanks to Duncan Murdoch for helpful pointers. Any errors are mine.

Setting a text = a string crashes my program

I am new at this so be gentle.
I have this function:
- (void) Morepoint {
gscore ++;
scoreString = [NSString stringWithFormat:#"%i", gscore];
lblscore.text = scoreString;
}
Where gscore is a global. scoreString is a NSString and lblscore is a label.
Every time I insert the function in my gameloop, the program stops to run.
Can anyone figure that out?
If I call the function from outside my gameloop, everything works fine, why?
You own the object returned from initWithFormat which you are responsible for releasing, but you don't own the object returned from stringWithFormat which returns an autoreleased string and so do not need to release it (if you do want to have ownership of it, you must retain it).
So for resolving your issue try to assign your value like this,
- (void) Morepoint
{
gscore ++;
scoreString = [[NSString alloc] initWithFormat:#"%i",gscore];
lblscore.text = scoreString;
}
Hope this helps you. Just Give it a try :)

Scintilla (QScintilla) 3rd marker define fails

In my class I attempt to define 3 markers, one for errors, one for warnings, and one for breakpoints. This worked well when I was only attempting to define 2 markers, but for some reason the third of these markers doesn't appear when added to a line. If you switch the ordering of the definitions, it is always the third one that fails to appear when markerAdd() is called. The pixmaps are valid, and Scintilla's return values appear to be correct for both defining and adding markers. This is more of a general Scintilla question rather than a QScintilla question I believe, because QScintilla simply does some checks before calling the underlying scintilla code. I have no idea where to even begin in debugging this code. If anyone can shed some light on this, whether it is a known scintilla quirk or it is my fault, I would be eternally grateful.
m_errorIndicator = ui_editor->markerDefine(QPixmap(":/sourcefile/icon_set/icons/bullet_red.png"));
m_breakIndicator = ui_editor->markerDefine(QPixmap(":/sourcefile/icon_set/icons/bullet_black.png"));
m_warningIndicator = ui_editor->markerDefine(QPixmap(":/sourcefile/icon_set/icons/bullet_yellow.png"));
void SourceFile::on_actionAddBreakpoint_triggered()
{
qWarning() << "Added breakpoint to " << m_currentLine;
qWarning() << ui_editor->markerAdd(m_currentLine, m_breakIndicator);
m_breakpoints.append(m_currentLine);
}
void SourceFile::on_actionRemoveBreakpoint_triggered()
{
ui_editor->markerDelete(m_currentLine, m_breakIndicator);
m_breakpoints.removeAll(m_currentLine);
}
void SourceFile::clearProblems()
{
ui_editor->markerDeleteAll(m_errorIndicator);
ui_editor->markerDeleteAll(m_warningIndicator);
}
void SourceFile::markProblems(const QStringList& errors, const QStringList& warnings)
{
foreach(const QString& error, errors) {
int line = error.section(":", 1, 1).toInt();
if(--line < 0) continue;
ui_editor->markerAdd(line, m_errorIndicator);
}
foreach(const QString& warning, warnings) {
int line = warning.section(":", 1, 1).toInt();
if(--line < 0) continue;
ui_editor->markerAdd(line, m_warningIndicator);
}
}
There should be a yellow bullet next to the printf statement. If the warning and breakpoint definitions are switched, the yellow bullet will show up and the black bullet will disappear.
Aha! After days of looking, I finally found the problem.
ui_editor->setMarginMarkerMask(1, m_breakpointMarker);
Was being called in a setup method, which was causing funky behavior. Removing this fixed everything.

Problem with stringByTrimmingCharactersInSet:

I'm doing a very simple trimming from a string. Basically it goes like this:
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#",s);
[pool drain];
return 0;
}
No matter how many times I check, I can't find a mistake on the code. But the compiler keeps returning:
Running…
2009-12-30 08:49:22.086 Untitled[34904:a0f] Some other string
It doesn't trim the string at all. Is there a mistake in my code, because I can't believe something this simple doesn't work. Thanks!
Edit:
I think I've figured my mistake. stringByTrimmingCharactersInSet only trims the string from the leftmost and rightmost ends of a string. Can anybody confirm this?
You are correct - with your code stingByTrimmingCharactersInSet will trim the left and right whitespace but leave internal whitespace alone.
Note that there's also a memory leak in your code sample:
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
This will leak when you re-assign to s in the next line.

Resources