Delphi - ADO query and FillChar generates errors - string

I have the following code:
var wqry:TAdoQuery;
...
FillChar(wSpaces,cSpacesAfter,' ');
try
wqry := TADOQuery.Create(nil);//here the error
wqry.Connection:=...
cSpacesAfter is a constant and has the value 1035. wSpaces is a local string variable. The problem is that I receive the following error when TAdoQuery is created
even it is in french, I believe you got the idea.....
If I comment the FillChar code, everything works ok. I have the usual compiler directives, nothing special. I'm using Delphi 7.
Can someone tell me what is wrong with that code?

The troublesome code is most likely this one
FillChar(wSpaces,cSpacesAfter,' ');
I'm assuming that wSpaces is of string type. A string variable is in fact nothing more than a pointer to the data structure that holds the string. You don't need to use pointer syntax because the compiler takes care of that for you.
So what this code does is overwrite the variable holding that pointer with 4 space characters and then write 1031 more spaces over the top of whatever follows the variable. In short you will completely corrupt your memory. That would explain why the FillChar works but the very next line of code dies a painful and dramatic death.
If your string indeed had space for 1035 characters your could instead write:
FillChar(wSpaces[1], cSpacesAfter, ' ');
However, if may be more idiomatic to write:
wSpaces := StringOfChar(' ', cSpacesAfter);

FillChar procedure fills out a section of storage Buffer with the same byte or character FillValue FillCount times.
It is principally used to initialise arrays of numbers. It can be used to initialise records and strings, but care should be used to avoid overwriting length fields. StringOfChar is best for filling out strings to the same character.
Are you sure wSpaces has the size enough to fit all of cSpacesAfter you write to it?

Related

Delphi: strange substring result

Delphi Seattle (S10). Win32 project.
Yesterday I got wrong result in my old routine.
I found this line:
sPre := Copy(aSQLText, p - 1, 1);
aSQLText was 'CREATE', and p = 1.
The sPre got "C" result.
Hmmm... Then I wrote to watch window:
Copy('ABC', 0, 1)
and the result was "A"...
Ouch... What???
The copy handles the overflow in the end well.
But not at the beginning? Or what?
I hope that I haven't got any codes which points to before the string.
Do you also got this result in your Delphi?
Why?
As I know the strings internally stored as 4 byte length + string; and they
based in 1 (not 0 as any arrays). Is this a bug?
The call to copy in your code is resolved to the internal function _UStrCopy from System.pas. Right in the beginning of its implementation it checks the Index and Count parameters and corrects them when necessary. This includes forcing the Index to point to the first character if it is too low.
I agree that this should be documented, though.
The documentation for Copy doesn't specify what will happen in this instance, so I wouldn't call it a Bug per se.
I can see arguments for both solutions (empty string or as it does, assume 1 as starting position).
Point is, as it is not defined in the documentation what happens in this instance, it is unwise for a program to assume anything one way or another, as it may be implementation dependent and might even change over the course of different versions. If your code can risk having p=1 (or even p=0) and you want the empty string in that case, you should explicitly write code to that effect instead of relying on your (wrong, in this case) expectation on what the compiler might do:
if p<=1 then sPre:='' else sPre := Copy(aSQLText, p - 1, 1);

MALAB Coder - Static size string in sprintf

How can I prevent MATLAB Coder to generate variable size code for a simple number insertion into a string?
for i=1:4
name=sprintf('Data%d.bin',int8(i));
stuff(name);
end
In the generated C code it uses a lot of functions like emxutil to determine the size of the generated string for sprtintf.
I just want to say that i is only one digit. How can I do that?!
The followings also do not work
name=['Data',char(i),'.bin'];
Using the following also gives an error for generating code that LHS is fixed sized but RHS is varying:
coder.varsize('name',[1,14],[0,0])
I just tested the following again. It works well and also can be used for more digits, and it does not use var size stuff.
name=['Data',int2str(i),'.bin'];
Also, these can be used if we are sure that i is one digit:
['Data' char(48+i) '.bin']
['Data' char('0'+i) '.bin']

Concatenation with empty string raises ERR:INVALID DIM

In TI-BASIC, the + operation is overloaded for string concatenation (in this, if nothing else, TI-BASIC joins the rest of the world).
However, any attempt to concatenate involving an empty string raises a Dimension Mismatch error:
"Fizz"+"Buzz"
FizzBuzz
"Fizz"+""
Error
""+"Buzz"
Error
""+""
Error
Why does this occur, and is there an elegant workaround? I've been using a starting space and truncating the string when necessary (doesn't always work well) or using a loop to add characters one at a time (slow).
The best way depends on what you are doing.
If you have a string (in this case, Str1) that you need to concatenate with another (Str2), and you don't know if it is empty, then this is a good general-case solution:
Str2
If length(Str1
Str1+Str2
If you need to loop and add a stuff to the string each time, then this is your best solution:
Before the loop:
" →Str1
In the loop:
Str1+<stuff_that_isn't_an_empty_string>→Str1
After the loop:
sub(Str1,2,length(Str1)-1→Str1
There are other situations, too, and if you have a specific situation, then you should post a simplified version of the relevant code.
Hope this helps!
It is very unfortunate that TI-Basic doesn't support empty strings. If you are starting with an empty string and adding chars, you have to do something like this:
"?
For(I,1,3
Prompt Str1
Ans+Str1
End
sub(Ans,2,length(Ans)-1
Another useful trick is that if you have a string that you are eventually going to evaluate using expr(, you can do "("+Str1+")"→Str1 and then freely do search and replace on the string. This is a necessary workaround since you can't search and replace any text involving the first or last character in a string.

need guidance with basic function creation in MATLAB

I have to write a MATLAB function with the following description:
function counts = letterStatistics(filename, allowedChar, N)
This function is supposed to open a text file specified by filename and read its entire contents. The contents will be parsed such that any character that isn’t in allowedChar is removed. Finally it will return a count of all N-symbol combinations in the parsed text. This function should be stored in a file name “letterStatistics.m” and I made a list of some commands and things of how the function should be organized according to my professors' lecture notes:
Begin the function by setting the default value of N to 1 in case:
a. The user specifies a 0 or negative value of N.
b. The user doesn’t pass the argument N into the function, i.e., counts = letterStatistics(filename, allowedChar)
Using the fopen function, open the file filename for reading in text mode.
Using the function fscanf, read in all the contents of the opened file into a string variable.
I know there exists a MATLAB function to turn all letters in a string to lower case. Since my analysis will disregard case, I have to use this function on the string of text.
Parse this string variable as follows (use logical indexing or regular expressions – do not use for loops):
a. We want to remove all newline characters without this occurring:
e.g.
In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
In my younger and more vulnerableyears my father gave me some advicethat I’ve been turning over in my mindever since.
Replace all newline characters (special character \n) with a single space: ' '.
b. We will treat hyphenated words as two separate words, hence do the same for hyphens '-'.
c. Remove any character that is not in allowedChar. Hint: use regexprep with an empty string '' as an argument for replace.
d. Any sequence of two or more blank spaces should be replaced by a single blank space.
Use the provided permsRep function, to create a matrix of all possible N-symbol combinations of the symbols in allowedChar.
Using the strfind function, count all the N-symbol combinations in the parsed text into an array counts. Do not loop through each character in your parsed text as you would in a C program.
Close the opened file using fclose.
HERE IS MY QUESTION: so as you can see i have made this list of what the function is, what it should do, and using which commands (fclose etc.). the trouble is that I'm aware that closing the file involves use of 'fclose' but other than that I'm not sure how to execute #8. Same goes for the whole function creation. I have a vague idea of how to create a function using what commands but I'm unable to produce the actual code.. how should I begin? Any guidance/hints would seriously be appreciated because I'm having programmers' block and am unable to start!
I think that you are new to matlab, so the documentation may be complicated. The root of the problem is the basic understanding of file I/O (input/output) I guess. So the thing is that when you open the file using fopen, matlab returns a pointer to that file, which is generally called a file ID. When you call fclose you want matlab to understand that you want to close that file. So what you have to do is to use fclose with the correct file ID.
fid = open('test.txt');
fprintf(fid,'This is a test.\n');
fclose(fid);
fid = 0; % Optional, this will make it clear that the file is not open,
% but it is not necessary since matlab will send a not open message anyway
Regarding the function creation the syntax is something like this:
function out = myFcn(x,y)
z = x*y;
fprintf('z=%.0f\n',z); % Print value of z in the command window
out = z>0;
This is a function that checks if two numbers are positive and returns true they are. If not it returns false. This may not be the best way to do this test, but it works as example I guess.
Please comment if this is not what you want to know.

How to use strstrip for parsing a string in two parts

I would like to know hot to parse a string like this "hello world" into "helloworld" using the strstrip kernel function. I am developing a Linux Kernel char device and this functions causes me a Kernel Panic (or Kernel Opss).
The way I'm using this function is the following:
char result[100];
strcpy(result, "hello world");
strstrip(result);
strstrip(&result); //Also tried this
strstrip("100+200"); //Also tried this
The Kernel error is caused as soon as the strstrip line gets executed. What is the proper way to call this function?
Actually strstrip helps to remove the white spaces at the front. It does not remove all the white spaces with in the string.
Please look at the below example.
char result[100];
strcpy(result, " hello world from stack exchange");
printk("\n before: %s",result);
strcpy(result, strstrip((char*)result));
printk("\n after: %s",result);
Hope it helps.
srtstrip() is a wrapper function for strim() (http://lxr.linux.no/linux+v3.11.2/lib/string.c#L361) in modern kernels. As it will attempt to modify the string itself, you cannot call it with a static string as you have in the third attempt.
The second attempt you have is passing a pointer to an array variable which is also a pointer. So you are passing a char** which if you look at the link above you can see is not correct.
The first attempt should not cause a kernel error, but you do not appear to be receiving the return value in a a local variable. What kind of error are you receiving? I will update this answer if you can provide that information.
In the end though as Balamurugan A points out, this function does not do what you seem to think it does. strsep() (http://lxr.linux.no/linux+v3.11.2/lib/string.c#L485) may help you out here but it will only be a stepping stone to removing all spaces. You will actually have to copy the string into a new buffer word by word as there is not way to simply "shift memory contents", as it were.

Resources