为啥应用 tranwrd 函数后最后一个字符被删除

Posted

技术标签:

【中文标题】为啥应用 tranwrd 函数后最后一个字符被删除【英文标题】:Why is the last character getting removed after applying tranwrd function为什么应用 tranwrd 函数后最后一个字符被删除 【发布时间】:2022-01-14 09:06:25 【问题描述】:

我想替换我的 json 文件中的某些值(在此示例中,空值带有空引号。)我的解决方案工作正常,但由于某种神秘的原因,json 文件的最后一个字符被删除。不管最后一个字符是什么,代码总是会删除它——我也尝试过使用不同的以花括号结尾的 json 文件。

这是什么原因造成的,更重要的是我该如何预防?

data testdata_;
input var1 var2 var3;
format _all_ commax10.1;
datalines;
 3.1582 0.3 1.8
 21 . .
 1.2 4.5 6.4
;
proc json out = 'G:\test.json' pretty fmtnumeric nosastags keys;
export testdata_;
run;

data _null_;
  infile 'G:\test.json';
  file 'G:\test.json';
  input;
  _infile_ = tranwrd(_infile_,'null','""');
  put _infile_ ;
run;

要查看内容如何变化,首先运行代码直到“data null”语句并检查文件内容,然后运行最后一条语句。

【问题讨论】:

写一个新文件。更改 FILE 语句以使用不同的文件名。 【参考方案1】:

Data _null_ 是否正确;不要写入同一个文件。 SAS 提供了这个选项,但在现代,它几乎总是是错误的答案,因为 SAS 对此提供了支持,而且存储足够便宜和快速。

在这种情况下,它看起来是一个相对简单的修复,但您可能应该按照建议进行操作并写入一个新文件 - 会有其他问题。

data testdata_;
input var1 var2 var3;
format _all_ commax10.1;
datalines;
 3.1582 0.3 1.8
 21 . .
 1.2 4.5 6.4
;
proc json out = 'H:\temp\test.json' pretty fmtnumeric nosastags keys;
export testdata_;
run;

data _null_;
  infile 'H:\temp\test.json' end=eof;
  file 'H:\temp\test.json';
  input @;
  putlog _infile_;
  _infile_ = tranwrd(_infile_,'null','""  ');
  
  len = length(_infile_);
  put _infile_ ;
  if eof then put _infile_;
run;

有两个变化。一、我在tranwrd中使用'"" '而不是'""';那是因为否则你会在添加新行时得到稍微奇怪的结果。如果您的 JSON 解析器不喜欢 "" ,,那么您可能想要两个 tranwrd,一个用于 null,,一个用于 null,或类似的东西(或使用正则表达式)。但重要的是输入和输出中需要匹配的字符数。如果你不能处理(比如多余的空格有问题),那么你就剩下“写一个新文件”了。

二,我寻找文件的结尾,然后故意在那里写出第二行。这避免了您在使用括号时遇到的问题,因为它避免了在括号之前写出 EOF。我不是 100% 确定我知道你为什么需要它 - 但你知道。

另一个可能更有意义的选择是只写有括号的行。

data _null_;
  infile 'H:\temp\test.json' sharebuffers; 
  file 'H:\temp\test.json';
  input @;
  putlog _infile_;
  if find(_infile_,'null') then do;
    _infile_ = tranwrd(_infile_,'null','"" ');  
    put _infile_;
  end;
run;

我添加了sharebuffers,因为这应该使它运行得更快一些。请注意,我还删除了一个空格 - SAS 这样做的方式有些奇怪,否则会从下一行中删除一个空格。不知道为什么,可能 EOL 字符有些奇怪。

但是,除非没有其他选择,否则不要这样做。写一个新文件。

【讨论】:

【参考方案2】:

一个奇怪的事情是,PROC JSON 总是写一个使用 LF 作为行尾字符的文本文件。

因此,如果添加这些警告,您也许可以覆盖文件:

    在 INFILE 语句中使用 TERMSTR=LF。 在 INFILE 语句中使用 SHAREDBUFFERS。 使用 TRANWRD() 函数替换具有相同字节数的字符串,并且不要将空格作为行的最后一个字符。

我还会搜索 ':null' 而不仅仅是 'null' 以降低替换文件中其他字符串中的这些字符的风险。

data _null_;
  infile json SHAREBUFFERS termstr=lf ;
  file json ;
  input ;
  _infile_ = tranwrd(_infile_,': null',':   ""');
  put _infile_;
run;

【讨论】:

我认为这是这里的具体问题 - 0D0A 被写出,并覆盖 0A5D(括号为 5D)。

以上是关于为啥应用 tranwrd 函数后最后一个字符被删除的主要内容,如果未能解决你的问题,请参考以下文章

当我删除核心数据实体的最后一条记录时,为啥我的应用程序崩溃了?

为啥我不能删除这个表格?

为啥只有我最后一个本地通知功能被调用?

为啥dma只接收最后一个字符

c语言如何删除输出的最后的一个字符?

为啥在 c++ 中分配 char 数组元素时,分配的字符被破坏?