Синтаксис для возврата одного символа строки по индексу - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь сравнить один символ строки, чтобы определить, является ли он моим символом-разделителем. Однако, когда я выполняю следующий код, значение, которое помещается в переменную valstring, представляет собой число, представляющее байт, который был преобразован в строку, а не сам символ. Например, значение может быть строкой «58».

Благодаря моему тестированию в CoDeSys с использованием функций отладки я знаю, что строка sReadLine содержит допустимую строку символов. Я просто не уверен в синтаксисе, чтобы выделить только один из них;sReadLine[valPos + i] часть - это то, что я не понимаю.

sReadLine : STRING;
valstring : STRING;
i         : INT;
valPos    : INT;

FOR i := 0 TO 20 DO
    IF BYTE_TO_STRING(sReadLine[valPos + i]) = '"' THEN
        EXIT;
    END_IF
    valstring := CONCAT(STR1 := valstring, STR2 := BYTE_TO_STRING(sReadLine[valPos + i]));
END_FOR

Ответы [ 2 ]

1 голос
/ 08 ноября 2019

Когда вы конвертируете байт в строку, то конвертируется цифровое представление байта. Это означает, что вы интерпретируете этот байт как символ ascii (десятичное значение ascii: 58).

Так что если вы хотите использовать символы Concat вместо их десятичного представления ascii, вам нужна другая функция:

valstring := CONCAT(STR1 := valstring, STR2 := F_ToCHR(sReadLine[valPos + i]));

РЕДАКТИРОВАТЬ:

Как Quirzo, я не мог найти аналогичную функцию F_ToCHR для Codesys, но вы могли бы легко создать ее самостоятельно. Например:

Часть декларации:

FUNCTION F_ASCII_TO_STRING : STRING
VAR_INPUT
    input : BYTE;
END_VAR
VAR
    ascii   : ARRAY[0..255] OF STRING(1):= 
    [
        33(' '),'!','"','#',
        '$$' ,'%' ,'&' ,'´',
        '(' ,')' ,'*' ,'+' ,
        ',' ,'-' ,'.' ,'/' ,
        '0' ,'1' ,'2' ,'3' ,
        '4' ,'5' ,'6' ,'7' ,
        '8' ,'9' ,':' ,';' ,
        '<' ,'=' ,'>' ,'?' , 
        '@' ,'A' ,'B' ,'C' ,
        'D' ,'E' ,'F' ,'G' ,
        'H' ,'I' ,'J' ,'K' ,
        'L' ,'M' ,'N' ,'O' ,
        'P' ,'Q' ,'R' ,'S' ,
        'T' ,'U' ,'V' ,'W' ,
        'X' ,'Y' ,'Z' ,'[' ,
        '\' ,']' ,'^' ,'_' ,
        '`' ,'a' ,'b' ,'c' ,
        'd' ,'e' ,'f' ,'g' ,
        'h' ,'i' ,'j' ,'k' ,
        'l' ,'m' ,'n' ,'o' ,
        'p' ,'q' ,'r' ,'s' ,
        't' ,'u' ,'v' ,'w' ,
        'x' ,'y' ,'z' ,'{' ,
        '|' ,'}' ,'~' 
    ];

END_VAR

Часть реализации:

F_ASCII_TO_STRING := ascii[input];
1 голос
/ 08 ноября 2019

Я думаю, у вас есть несколько вариантов.

1) Вместо этого используйте встроенные строковые функции. Вы можете использовать функцию MID, чтобы получить часть строки. Так что в вашем случае что-то вроде «получить один символ из valPos + 1 из sReadLine.

FOR i := 0 TO 20 DO
    IF MID(sReadLine, 1, valPos + i) = '"' THEN
        EXIT;
    END_IF
    valstring := CONCAT(STR1 := valstring, STR2 := MID(sReadLine, 1, valPos + i));
END_FOR

2) Преобразовать байт ASCII в строку. В системах TwinCAT есть функция F_ToCHR. Он принимает байт ASCII и возвращает символ в виде строки. Я не могу найти что-то подобное для Codesys, но я уверен, что в какой-то библиотеке будет решение. Поэтому, пожалуйста, обратите внимание, что это победило 't работает в Codesys без изменений:

FOR i := 0 TO 20 DO
    IF F_ToCHR(sReadLine[valPos + i]) = '"' THEN
        EXIT;
    END_IF
    valstring := CONCAT(STR1 := valstring, STR2 := F_ToCHR(sReadLine[valPos + i]));
END_FOR

3) Библиотека OSCAT , кажется, имеет функцию CHR_TO_STRING. Вы можете использовать ее вместо F_ToCHR на шаге 2.

4) Вы можете использовать указатели для копирования байта ASCII в строковый массив (MemCpy) и добавления символа конца строки. Это требует некоторых знаний указателей и т. Д. См. Форум Codesys для некоторых примеров.

5) Вы можете написать вспомогательную функцию, подобную шагу 2. Проверьте пример с форумов Codesys . Этот пример не включает все символы, поэтому его необходимо обновить. Он не совсем элегантный.

...