I just use CreateFile, ReadFile, WriteString, and ReadString. Nothing fancy, but it means the format is exact.
Space in preference string
Re: Space in preference string
Re: Space in preference string
First try
attempt number two
Code: Select all
EnableExplicit
Structure ini
filepath.s
file_id.i
format.i
pos.i
EndStructure
Procedure ini_Open(*inifile.ini)
*inifile\file_id = ReadFile(#PB_Any, *inifile\filepath)
*inifile\format = ReadStringFormat(*inifile\file_id)
EndProcedure
Procedure ini_SetGroup(*inifile.ini, Group$)
Protected String$
If *inifile\file_id
FileSeek(*inifile\file_id, 0)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
; Debug "|" + String$ + "|"
If String$ = "[" + Group$ + "]"
*inifile\pos = Loc(*inifile\file_id)
; Debug "найдено"
Break
EndIf
Wend
EndIf
EndProcedure
Procedure.s ini_GetValue(*inifile.ini, Key$)
Protected String$, Result$, pos2
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
pos2 = FindString(String$, "=")
If Asc(String$) = '['
Break
EndIf
If pos2 And Left(String$, pos2 - 1) = Key$
Result$ = Mid(String$, pos2 + 1)
Break
EndIf
Wend
EndIf
ProcedureReturn Result$
EndProcedure
; Procedure ini_Close(*inifile.ini)
; CloseFile(*inifile\file_id)
; EndProcedure
Global inifile.ini
inifile\filepath = "C:\PB\Source\Current\ini\1.ini"
ini_Open(inifile)
If inifile\file_id
Debug "Size = " + Str(FileSize(inifile\filepath))
Debug "file_id = " + Str(inifile\file_id)
ini_SetGroup(inifile.ini, "fuf")
Debug "pos = " + Str(inifile\pos)
Debug ini_GetValue(inifile.ini, "param")
CloseFile(inifile\file_id)
EndIfCode: Select all
;- AZJIO 08.09.2024
EnableExplicit
; Structure CacheGroups
; name.s
; pos.i
; EndStructure
Structure ini
filepath.s
file_id.i
format.i
pos.i
; List GroupPosList.CacheGroups()
EndStructure
Procedure ini_Open(*inifile.ini)
*inifile\file_id = OpenFile(#PB_Any, *inifile\filepath)
*inifile\format = ReadStringFormat(*inifile\file_id)
EndProcedure
Procedure ini_SetGroup(*inifile.ini, Group$)
Protected String$, *start, *c.Character
If *inifile\file_id
FileSeek(*inifile\file_id, 0)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
; Debug "open"
; кешировать группы при чтении, чтобы не искать позицию.
*c + SizeOf(Character)
*start = *c
While *c\c
If *c\c = ']'
*c\c = 0
String$ = PeekS(*start)
; Debug "|" + String$ + "|"
If String$ = Group$
*inifile\pos = Loc(*inifile\file_id)
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
Default
Break
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
EndProcedure
Procedure.s ini_GetValue(*inifile.ini, Key$)
Protected String$, tmp$, *start, *c.Character, Result$; = -2147483646
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
Break 2 ; открывается новая группа, не найдено, выпрыгиваем
Default
*start = *c
*c + SizeOf(Character)
While *c\c
If *c\c = '='
*c\c = 0
tmp$ = RTrim(PeekS(*start))
; Debug "|" + tmp$ + "|"
If tmp$ = Key$
Result$ = PeekS(*c + SizeOf(Character))
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
ProcedureReturn Result$
EndProcedure
Procedure ini_SetValue(*inifile.ini, Key$, Value$)
Protected String$, tmp$, tmp2$, *mem, filepos, *start, *c0, *c.Character, Result; = -2147483646
If *inifile\file_id
FileSeek(*inifile\file_id, *inifile\pos)
While Eof(*inifile\file_id) = 0
filepos = Loc(*inifile\file_id)
String$ = ReadString(*inifile\file_id, *inifile\format)
*c = @String$
*c0 = *c
; Debug "String$ = " + String$
While *c\c
Select *c\c
Case 32, 9 ; пробел, табуляция
*c + SizeOf(Character)
Continue
Case '['
Break 2 ; открывается новая группа, не найдено, выпрыгиваем
Default
*start = *c
*c + SizeOf(Character)
While *c\c
If *c\c = '='
*c\c = 0
String$ = RTrim(PeekS(*start))
; Debug "|" + String$ + "|"
If String$ = Key$
tmp$ = ReadString(*inifile\file_id, *inifile\format + #PB_File_IgnoreEOL) ; читаем остаток до конца строки
FileSeek(*inifile\file_id, filepos) ; перемещаем указатель в позицию до чтения параметра
tmp2$ = Key$ + "=" + Value$ + #CRLF$
Select *inifile\format
Case #PB_Ascii
*mem = Ascii(tmp2$)
WriteData(*inifile\file_id, *mem, StringByteLength(tmp2$, #PB_Ascii))
FreeMemory(*mem)
Case #PB_UTF8
*mem = UTF8(tmp2$)
WriteData(*inifile\file_id, *mem, StringByteLength(tmp2$, #PB_UTF8))
FreeMemory(*mem)
Case #PB_Unicode
WriteString(*inifile\file_id, tmp2$, *inifile\format) ; записываем строку
EndSelect
WriteString(*inifile\file_id, tmp$, *inifile\format) ; записываем остаток
TruncateFile(*inifile\file_id)
Result = 1
; Debug "найдено"
Break 3
EndIf
EndIf
*c + SizeOf(Character)
Wend
EndSelect
*c + SizeOf(Character)
Wend
Wend
EndIf
ProcedureReturn Result
EndProcedure
; Procedure ini_Close(*inifile.ini)
; CloseFile(*inifile\file_id)
; EndProcedure
Global inifile.ini
inifile\filepath = "C:\PB\Source\Current\ini\1.ini"
ini_Open(inifile)
If inifile\file_id
Debug "Size = " + Str(FileSize(inifile\filepath))
Debug "file_id = " + Str(inifile\file_id)
ini_SetGroup(inifile.ini, "fuf")
Debug "pos = " + Str(inifile\pos)
Debug ini_GetValue(inifile.ini, "param")
Debug ini_SetValue(inifile.ini, "param", "кукареку-абракадабра")
CloseFile(inifile\file_id)
EndIf
Last edited by AZJIO on Sun Sep 08, 2024 3:58 pm, edited 1 time in total.
Re: Space in preference string
Here is another (good) one....
kenmo's ini.pbi
@AZJIO: No offense, but please look at the typo: Groop -> Group
kenmo's ini.pbi
@AZJIO: No offense, but please look at the typo: Groop -> Group
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Re: Space in preference string
there are in the forum several workarounds and alternative procedures to the purebasic preference library, but that doesn't take away from the fact that in my opinion it is a bug, readpreference is not normal that it deletes all the spaces to the left of the string or is it?

Re: Space in preference string
Again today in one of my apps I was going crazy trying to find where the problem was, and the problem is always the preference function that removes spaces at the beginning of the field, I always have to come up with something every time to work around the problem, @Fred please report this as a bug, I didn't see written anywhere that the preference library cuts you spaces from strings

Re: Space in preference string
Yes, but before in the title of the discussion it was BUG and now it's not there, that's why I thought maybe it was discarded and not considered as a bug

Re: Space in preference string
I don't think it's a bug, as if you are using a prefs file, it meant to be manually edited so spaces shouldn't be relevant. You can still use a special char or put the string inside quotes to be sure to preserve them.
Re: Space in preference string
Thanks for the reply Fred. yes I use such a system I encapsulate the initial spaces and then I make an unescape, but it is not the most intuitive thing in the world and in the help file it is not specified that the initial spaces are deleted arbitrarily, I suppose it would be better to warn in the help file, at least if someone else runs into this thing(which for me is a bug not being reported in the guide) at least he does not go crazy to figure out where the problem is, thanks for everything you are always very kind 

Re: Space in preference string
The #PB_Preference_NoSpace constant means that by default, without this constant, there is a space after the "=" sign and it is not data. A space is the separator between the "=" sign and the start of data, so all spaces are ignored until a character other than a space appears. In this case, quotes are used to define the beginning of the data when the first character at the beginning may be a space. WinAPI functions work in the same way, so this is not a special rule, this rule has been in effect for decades, it is the ini file format that you need to know. Also the tab character is a whitespace character and is also ignored.le_magn wrote: Fri Dec 20, 2024 7:14 pm and in the help file it is not specified that the initial spaces are deleted arbitrarily, I suppose it would be better to warn in the help file
Re: Space in preference string
Ok I understand, but since I'm a beginner in programming I don't know many things, but precisely because I didn't know if it had been specified in the help file that the spaces before the data were all eliminated I would have saved myself a big headache a while ago, now I know and I'm certainly more careful, thanks for the explanationAZJIO wrote: Fri Dec 20, 2024 9:01 pm The #PB_Preference_NoSpace constant means that by default, without this constant, there is a space after the "=" sign and it is not data. A space is the separator between the "=" sign and the start of data, so all spaces are ignored until a character other than a space appears. In this case, quotes are used to define the beginning of the data when the first character at the beginning may be a space. WinAPI functions work in the same way, so this is not a special rule, this rule has been in effect for decades, it is the ini file format that you need to know. Also the tab character is a whitespace character and is also ignored.



