How to cut a string to some desired number in delphi?
Asked Answered
C

4

13

I have a database column which can take only 40 characters of a string. So when the length of string is greater than 40 characters, its giving me error. How can I cut/trim the string to 40 characters in delphi?

Centuple answered 18/2, 2013 at 12:26 Comment(1)
Is the part about DB column length really relevant here? because if it does you can have several approaches here, for example setting field size will truncate the string, or using a CAST/other SQL string functions in query itself... (I would rethink about how to improve my DB design in such case).Roller
G
25
var
  s: string;
begin
  s := 'This is a string containing a lot of characters.'
  s := Copy(s, 1, 40);
  // Now s is 'This is a string containing a lot of cha'

More fancy would be to add ellipsis if a string is truncated, to indicate this more clearly:

function StrMaxLen(const S: string; MaxLen: integer): string;
var
  i: Integer;
begin
  result := S;
  if Length(result) <= MaxLen then Exit;
  SetLength(result, MaxLen);
  for i := MaxLen downto MaxLen - 2 do
    result[i] := '.';
end;

var
  s: string;
begin
  s := 'This is a string containing a lot of characters.'
  s := StrMaxLen(S, 40)
  // Now s is 'This is a string containing a lot of ...'

Or, for all Unicode lovers, you can keep two more original characters by using the single ellipsis character … (U+2026: HORIZONTAL ELLIPSIS):

function StrMaxLen(const S: string; MaxLen: integer): string;
var
  i: Integer;
begin
  result := S;
  if Length(result) <= MaxLen then Exit;
  SetLength(result, MaxLen);
  result[MaxLen] := '…';
end;

var
  s: string;
begin
  s := 'This is a string containing a lot of characters.'
  s := StrMaxLen(S, 40)
  // Now s is 'This is a string containing a lot of ch…'

But then you must be positive that all your users and their relatives support this uncommon character.

Goodell answered 18/2, 2013 at 12:27 Comment(8)
I would suggest using the proper ellipsis character at the end for this, thus keeping two additional characters in the string.Kauai
@mj2008: Added that option.Goodell
the character is also hex 85 in the ANSI character sets (I've used it in Delphi for many years). Obviously anyone using it should ensure it is valid in their code page or whatever.Kauai
@mj2008: But $85 is beyond 127, and so not particularly safe. It's much safer to use Unicode, then.Goodell
OK, now I see that most agree on this character, but it is not the same in Unicode, and we all need Unicode anyway. For instance, if you do Alt+0133 in Notepad, the actual character inserted is U+2026.Goodell
I think the Unicode option is better generally. The actual implementation can be left as an exercise for the reader...Kauai
@mj2008: Definitely. (The code above is purely Unicode, of course. Indeed, SO is Unicode. The character above is U+2026, and so the .pas files need to be saved as Unicode.)Goodell
Very nice answer as always. Also thank for the unicode char hint. I hope your health is better now! Take care!!!Irriguous
O
19

You can use SetLength for this job:

SetLength(s, Min(Length(s), 40));
Ojibwa answered 18/2, 2013 at 12:31 Comment(5)
I just added that. (Unadded that when I saw your answer.)Goodell
This is the best approach, performance-wise, if you work with very long strings (many MBs) or very many strings (thousands per sec or so).Goodell
I think this is the best approach performance and coding-wise.Taxeme
For very long strings, it will allocate a new memory block so it WON'T be faster than copy(). So imho using Setlength in this case is just overcomplicated. Copy() will allocate a new string but will make reference counting more direct, and will be more standard. This code is just premature optimization.Corfu
@ArnaudBouchez I personally said nothing about optimization. I wasn't thinking about performance. It's just how I would truncate a string to a specific maximum length. I don't think optimization and performance is important here. Heck, we are about to push this to a DB. Let's get our priorities in order. As an aside, this makes a rather surprising change, namely you accusing me of PO. It's usually the other way around! ;-)Ojibwa
N
14
var s : string;
begin   
   s := 'your string with more than 40 characters...';
   s := LeftStr(s, 40);
Nelle answered 18/2, 2013 at 12:29 Comment(3)
You need StrUtils for this.Goodell
I am wonder, is this faster than SetLength or Copy approach?Manes
internally LeftStr executes a Copy command, so it is not faster.Nelle
G
0

Inspired by this solution in java , my solution was something like this (shorten a path which may be very long)

   const
      maxlen = 77;   // found this by entering sample text

  begin
     headlineTemp := ExtractFileName(main.DatabaseFileName);
     if length(main.DatabaseFileName) > maxlen then
      begin
        pnlDBNavn.Caption :=
             MidStr(
                  main.DatabaseFileName, 1,
                           maxlen -3 - length(headlinetemp)
                ) + '...\' + headlineTemp;
      end
     else
         // name is shorter, so just display it
         pnlDBNavn.Caption := main.DatabaseFileName;
   end;
Greengage answered 14/1, 2021 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.