Task: Append a record to the end of a text file


C++: #include <iostream>
#include <fstream>
#include <string>
#include <vector>

std::ostream& operator<<(std::ostream& out, const std::string s) {
    return out << s.c_str();
}

struct gecos_t {
    std::string fullname, office, extension, homephone, email;

    friend std::ostream& operator<<(std::ostream&, const gecos_t&);
};

std::ostream& operator<<(std::ostream& out, const gecos_t& g) {
    return out << g.fullname << ',' << g.office << ',' << g.extension << ',' << g.homephone << ',' << g.email;
}

struct passwd_t {
    std::string account, password;
    int uid, gid;
    gecos_t gecos;
    std::string directory, shell;

    passwd_t(const std::string& a, const std::string& p, int u, int g, const gecos_t& ge, const std::string& d, const std::string& s)
        : account(a), password(p), uid(u), gid(g), gecos(ge), directory(d), shell(s)
    {
        
    }

    friend std::ostream& operator<<(std::ostream&, const passwd_t&);
};

std::ostream& operator<<(std::ostream& out, const passwd_t& p) {
    return out << p.account << ':' << p.password << ':' << p.uid << ':' << p.gid << ':' << p.gecos << ':' << p.directory << ':' << p.shell;
}

std::vector<passwd_t> passwd_list{
    {
        "jsmith", "x", 1001, 1000,
        {"Joe Smith", "Room 1007", "(234)555-8917", "(234)555-0077", "jsmith@rosettacode.org"},
        "/home/jsmith", "/bin/bash"
    },
    {
        "jdoe", "x", 1002, 1000,
        {"Jane Doe", "Room 1004", "(234)555-8914", "(234)555-0044", "jdoe@rosettacode.org"},
        "/home/jdoe", "/bin/bash"
    }
};

int main() {
    
    std::ofstream out_fd("passwd.txt");
    for (size_t i = 0; i < passwd_list.size(); ++i) {
        out_fd << passwd_list[i] << '\n';
    }
    out_fd.close();

    
    out_fd.open("passwd.txt", std::ios::app);
    out_fd << passwd_t("xyz", "x", 1003, 1000, { "X Yz", "Room 1003", "(234)555-8913", "(234)555-0033", "xyz@rosettacode.org" }, "/home/xyz", "/bin/bash") << '\n';
    out_fd.close();

    
    std::ifstream in_fd("passwd.txt");
    std::string line, temp;
    while (std::getline(in_fd, temp)) {
        
        if (!temp.empty()) {
            line = temp;
        }
    }
    if (line.substr(0, 4) == "xyz:") {
        std::cout << "Appended record: " << line << '\n';
    } else {
        std::cout << "Failed to find the expected record appended.\n";
    }

    return 0;
}




Java: import static java.util.Objects.requireNonNull;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class RecordAppender {
    static class Record {
        private final String account;
        private final String password;
        private final int uid;
        private final int gid;
        private final List<String> gecos;
        private final String directory;
        private final String shell;

        public Record(String account, String password, int uid, int gid, List<String> gecos, String directory, String shell) {
            this.account = requireNonNull(account);
            this.password = requireNonNull(password);
            this.uid = uid;
            this.gid = gid;
            this.gecos = requireNonNull(gecos);
            this.directory = requireNonNull(directory);
            this.shell = requireNonNull(shell);
        }

        @Override
        public String toString() {
            return account + ':' + password + ':' + uid + ':' + gid + ':' + String.join(",", gecos) + ':' + directory + ':' + shell;
        }

        public static Record parse(String text) {
            String[] tokens = text.split(":");
            return new Record(
                    tokens[0],
                    tokens[1],
                    Integer.parseInt(tokens[2]),
                    Integer.parseInt(tokens[3]),
                    Arrays.asList(tokens[4].split(",")),
                    tokens[5],
                    tokens[6]);
        }
    }

    public static void main(String[] args) throws IOException {
        List<String> rawData = Arrays.asList(
                "jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8917,(234)555-0077,[email protected]:/home/jsmith:/bin/bash",
                "jdoe:x:1002:1000:Jane Doe,Room 1004,(234)555-8914,(234)555-0044,[email protected]:/home/jdoe:/bin/bash",
                "xyz:x:1003:1000:X Yz,Room 1003,(234)555-8913,(234)555-0033,[email protected]:/home/xyz:/bin/bash"
        );

        List<Record> records = rawData.stream().map(Record::parse).collect(Collectors.toList());

        Path tmp = Paths.get("_rosetta", ".passwd");
        Files.createDirectories(tmp.getParent());
        Files.write(tmp, (Iterable<String>) records.stream().limit(2).map(Record::toString)::iterator);

        Files.write(tmp, Collections.singletonList(records.get(2).toString()), StandardOpenOption.APPEND);

        try (Stream<String> lines = Files.lines(tmp)) {
            lines.map(Record::parse).forEach(System.out::println);
        }
    }
}