Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
D中的3D字符数组有问题_D - Fatal编程技术网

D中的3D字符数组有问题

D中的3D字符数组有问题,d,D,我正在学习D,我有一个简单的程序,可以逐行读取文本文件,将每行分割成不同的单词,然后将整个内容打印到标准输出 import std.stdio; import std.string; void main(string args[]) { char[][][] lines; auto input = File(args[1], "r"); foreach(line; input.byLine()) { auto words = split(stri

我正在学习D,我有一个简单的程序,可以逐行读取文本文件,将每行分割成不同的单词,然后将整个内容打印到标准输出

import std.stdio;
import std.string;

void main(string args[])
{
    char[][][] lines;
    auto input = File(args[1], "r");
    foreach(line; input.byLine())
    {
        auto words = split(strip(line));
        lines ~= words;
    }

    foreach(line; lines)
    {
        writeln(line);
    }
}
创建
单词的代码可以正常工作。如果每次分配单词时只调用
writeln
,我就会得到想要的输出。但是如果我在
中添加
单词
,并输出
,那么奇怪的事情就会发生<代码>行
在源文件中的每一行都有一个条目,但每一行都是上次读取的损坏版本。例如,如果文件的最后一行如下所示:

END    START        * End of routine
[       , END, ST, *, End , f rout, ne,    ,     , e other]
[     , END, ST, *, End of, rout, ne,      ,   , e othe]
[    , END, STAR, *, End of, rout, ne.,        
e]
[    , END, START  , *, End of, rout, ne.,        
e]
[END , STAR]
[     , END, START     , *, End , f , out, ne.  ]
[END, START, *, End, of ro, tine. ,  ,   ,  
]
[END, STA, *, o,  r, ut]
[  , END , S, *, End, o,  r, utine.,  ,   ,  , 
,  o]
[END, START    , *, of routi, e.,   ]
我得到的输出如下所示:

END    START        * End of routine
[       , END, ST, *, End , f rout, ne,    ,     , e other]
[     , END, ST, *, End of, rout, ne,      ,   , e othe]
[    , END, STAR, *, End of, rout, ne.,        
e]
[    , END, START  , *, End of, rout, ne.,        
e]
[END , STAR]
[     , END, START     , *, End , f , out, ne.  ]
[END, START, *, End, of ro, tine. ,  ,   ,  
]
[END, STA, *, o,  r, ut]
[  , END , S, *, End, o,  r, utine.,  ,   ,  , 
,  o]
[END, START    , *, of routi, e.,   ]

你知道我做错了什么吗?

你的主要问题是署名使用了相同的缓冲区,你需要复制它,这样它就不会覆盖你的数据

auto words = split(strip(line).dup);
更合适的存储类是string而不是char[],除非您打算修改实际字符。但是,在v2.0中会出现一个编译器错误,因为行将是char[]。这只是将其复制为不可变字符串的问题

auto words = split(strip(line).idup);
这样,您的程序看起来就像

import std.stdio;
import std.string;

void main(string[] args)
{
    string[][] lines;
    auto input = File(args[1], "r");
    foreach(line; input.byLine())
    {
        auto words = split(strip(line).idup);
        lines ~= words;
    }

    foreach(line; lines)
    {
        writeln(line);
    }
}

答案是双重的

首先,如上所述,
byLine
使用一个内部缓冲区(用于速度),它在后续循环迭代中被覆盖

其次,查看
单词的操作<代码>拆分(条(线))
strip
仅修改数组(作为引用)的开始和结束,而split将数组拆分为引用相同基础数据的较小子数组。两者都不是破坏性的;因此,两者都不需要重新分配。因此,最后的
string[]words
仍然指向原始缓冲区,该缓冲区在下一次写入时被覆盖

解决方案是,如果希望数据跳出循环范围,请通过写入
autowords=split(strip(line).dup)来确保复制数据。请注意,复制
字将不起作用,因为这只会复制数组数组,而不会复制数组本身


此外,还应使用
string[]args
。类似C的语法仅因遗留原因而受支持,不建议使用。

并非真正出于遗留原因,string只是D1中char[]和D2中immutable(char)[]的别名。建议使用它,因为它更易于读取,并且比不可变(char)[]更易于写入。当然,“自动”也有帮助。但是,如果您想在D2中使用可变字符串,则必须使用char[]。不,我的意思是
字符串args[]
。将
[]
放在参数后面。顺便说一句,您可能希望将
[i]dup
放在
条带之后,以节省少量内存。为什么使用
char[][][]
会导致编译失败?诚然,这是丑陋的,但应该仍然有效。我开始使用它是因为我在转换
char[][]
这个
split(strip(line))
返回的
char[]
string[]
之间遇到了很多问题。在任何情况下,您的解决方案都是有效的。谢谢。@Max,对不起,你说得对。我以为你只是在添加char[]。我会更新我的答案。