Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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
在C+中读取行后删除行+;使用系统()的程序 我试图理解C++中的文件I/O如何在C++或C中处理。我的目标是逐行读取文件,并将这些行发送到远程服务器。如果发送了该行,我想将其从文件中删除 我尝试的一种方法是保持读取的行数,并调用system()system调用来删除“count”行数。我使用了bash命令:sed-I-e1,'count'd filename 之后,我继续阅读该文件,令人惊讶的是,它按计划工作。 我有两个问题: 这样可靠吗 为什么这一切都有效呢 阅读文件时,我删除了其中的一部分,但它仍然有效?如果我 a是否寻求以前的职位,然后呢_C++_Bash_Sed - Fatal编程技术网

在C+中读取行后删除行+;使用系统()的程序 我试图理解C++中的文件I/O如何在C++或C中处理。我的目标是逐行读取文件,并将这些行发送到远程服务器。如果发送了该行,我想将其从文件中删除 我尝试的一种方法是保持读取的行数,并调用system()system调用来删除“count”行数。我使用了bash命令:sed-I-e1,'count'd filename 之后,我继续阅读该文件,令人惊讶的是,它按计划工作。 我有两个问题: 这样可靠吗 为什么这一切都有效呢 阅读文件时,我删除了其中的一部分,但它仍然有效?如果我 a是否寻求以前的职位,然后呢

在C+中读取行后删除行+;使用系统()的程序 我试图理解C++中的文件I/O如何在C++或C中处理。我的目标是逐行读取文件,并将这些行发送到远程服务器。如果发送了该行,我想将其从文件中删除 我尝试的一种方法是保持读取的行数,并调用system()system调用来删除“count”行数。我使用了bash命令:sed-I-e1,'count'd filename 之后,我继续阅读该文件,令人惊讶的是,它按计划工作。 我有两个问题: 这样可靠吗 为什么这一切都有效呢 阅读文件时,我删除了其中的一部分,但它仍然有效?如果我 a是否寻求以前的职位,然后呢,c++,bash,sed,C++,Bash,Sed,最好的,迪格维杰 附言: 如果有人能提出更好的办法,我会很高兴的 下面是我编写的程序的代码: #include<iostream> #include<fstream> #include<string> #include<sstream> #include<cstdlib> int main(){ std::ifstream f; std::string line; std::stringstream ss;

最好的,迪格维杰

附言:
如果有人能提出更好的办法,我会很高兴的

下面是我编写的程序的代码:

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<cstdlib>

int main(){
    std::ifstream f;
    std::string line;
    std::stringstream ss;
    int i=0;
    f.open("in.txt");
    if(f.is_open()){
        while(getline(f,line)){
            std::cout<<line<<std::endl;
            i++;
            if(i==2)break;
        }
        ss<<"sed -i -e 1,"<<i<<"d in.txt";
        system(ss.str().c_str());
        while(getline(f,line)){
            std::cout<<line<<std::endl;
        }
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
int main(){
std::iff流;
std::字符串行;
std::stringstream-ss;
int i=0;
f、 打开(“in.txt”);
如果(f.是开着的()){
while(getline(f,line)){

std::cout首先,尽可能避免使用
系统
调用(如果可能,根本不要使用),因为它们会造成竞争条件和其他问题,这些问题非常严重(而且经常发生)。如果涉及到文件访问,尤其如此

考虑到您的问题,有很多方法可以做到这一点,每种方法都有自己的注意事项

我将介绍三种可能的解决方案:

1) 如果文件足够小:

  • 您可以在数据结构(向量、列表、deque等)中读取整个内容
  • 删除原始文件
  • 确定要读取的行数(并通过服务器协议发送)
  • 然后将剩余的行作为原始文件的名称写入
  • 如果以后打算并行化程序,如果文件较小,这可能是一个更好的解决方案。注意:较小是一个相对术语,但通常受可用内存的限制

    2) 如果文件相当大或受内存限制,则必须使用缓冲区进行创作。一旦读取了一行并通过程序成功发送,则可以确定文件指针的位置,并将剩余信息作为新文件复制到当前文件的结尾。完成后,关闭并删除该文件旧文件,然后关闭新文件并将其重命名为与旧文件相同的名称

    < P > 3)如果你的解决方案不必在C++中,你可以使用shell脚本或(有争议的)另一种语言来完成任务。

    < P > 1)不,不可靠。

    2)C++运行库在块中(内部)读取文件,然后将其分为(高级)输入请求,直到块被耗尽,强制(内部)从磁盘读取更多块。由于在调用

    sed
    之前读取了一个或多个物理块,因此,如果
    sed
    碰巧更改了文件的第一部分,则无法对其进行更改


    若要查看代码失败,您需要将输入文件设置为足够大,以便在调用
    sed
    “fail”之前(运行库内部)仍有未读入的文件块我的意思是,在
    sed
    删除一些行之前,您的程序不会看到文件中原来的所有字符。

    sed编写文件的新版本,而程序一直读取它打开的同一版本。这是Unix和Linux的常见行为,当一个程序编写另一个程序打开的文件时。

    > 您可以通过这个小C程序自己看到这一点:

    #include <stdlib.h>
    #include <stdio.h>
    
    int main(void) {
        FILE *f = fopen("in.txt", "r");
        while (1) {
            rewind(f);
            int lines = 0;
            int c;
            while ((c = getc(f)) != EOF)
                if (c == '\n')
                    ++lines;
            printf("Number of lines in file: %d\n", lines);
        }
        return 0;
    }
    
    #包括
    #包括
    内部主(空){
    文件*f=fopen(“in.txt”,“r”);
    而(1){
    倒带(f);
    int行=0;
    INTC;
    而((c=getc(f))!=EOF)
    如果(c=='\n')
    ++线条;
    printf(“文件中的行数:%d\n”,行);
    }
    返回0;
    }
    
    在一个窗口中运行该程序,然后在另一个窗口中使用sed编辑该文件。即使磁盘上的文件已被编辑,该程序打印的行数也将保持不变,这是因为Unix保留旧的开放版本,即使其他程序无法再访问它

    关于你的第一个问题,你的解决方案是多么的可靠,据我看,它应该是可靠的,除了通常的警告系统崩溃或在更新过程中内存用完,其他人访问文件,当然还有“强”系统< /强>调用的所有问题。对于大型数据集,您可能希望采用不同的方式


    sujin关于为要保留的行使用临时文件的评论似乎是合理的。这将更快更安全。保留原始文件,这样如果系统崩溃,您仍然可以保留数据,并等待完成将旧文件重命名为“in.txt.bak”,然后将临时文件重命名为“in.txt”.

    正如其他人所说,在读取原始文件后,您必须使用所需的记录创建另一个文件,然后将其删除。但是在这个应用程序中,您可能会看到fifo比文件更有用。如果您在*NIX平台上,请从控制台检查makefifo语句


    这就像一个具有奇异性的文件,在读取一行之后,它会被删除。

    大多数现代文件系统不支持删除文件开头的行,因此这样做会非常低效


    解决实际问题的正常方法是在日志文件达到一定大小时停止写入,然后开始写入新文件。一旦写入整个文件,复制这些文件的代码就可以删除整个文件(这是一种有效的操作)。

    创建另一个临时文件并复制您需要的行