How to append to an array in C

Question from Deleted User

is there a way to append to an array in C

not linked lists

i have a callback function which needs to add an item to an array every time it's called

i can't figure out how to do that

Conceptually an array is not a good fit for continual appending. If you want to do an operation like that you would be best off writing or finding your own "ArrayList" kind of wrapper.

is there a way to find the index of the last item in the list

array*

An array in c is a fixed size block of memory that you have a pointer to the start of.

It is up to you to keep track of the size of that array usually in a separate int.

Because you only have the pointer to the start of the block of memory, nothing about that pointer can tell you how much memory ahead of that you are allowed to access.

So if you keep the size of the array and the pointer to the start of the array held somewhere then the "index of the last item" is something you implicitly know.

I might be wrong when I say to store it in an int it might be a usize or some other type.

time to check out rust

if anyone can help me out with this i might consider going back to C

The type you are looking for in rust is probably Vec.

Can you share your problem and what you were thinking of for a solution? I can maybe whip up a quick A/B of what it would be in C vs Rust.

I have a function which retrieves a few rows from a database and uses a callback function to individually process each row. The callback function is supposed to map the row's data to a structure and add it to an array.

this is what i was trying to do

void handle_entry(void *entries, int argc, char **argv, char **column_name){
  Entry entry;
  strcpy(entry.title, argv[1]);
  strcpy(entry.content, argv[2]);
}

void get_entries(){
  sqlite3 *DB;
  sqlite3_stmt *stmt;
  char *sql = "SELECT * FROM Entries;";
  Entry *entries[100];
  sqlite3_open("entries.db", &DB);
  sqlite3_exec(DB, sql, handle_entry, entries, 0);

What is the schema for entries?

ID, Title, Content

typedef struct Entry {
  int ID;
  char *title;
  char *content;
} Entry;
CREATE TABLE Entries(
              ID INTEGER PRIMARY KEY,
              Title CHAR(512),
              Content TEXT);

Here ya go

use rusqlite::{Connection, NO_PARAMS};

#[derive(Debug)]
struct Entry {
    id: i64,
    title: String,
    content: String
}

fn insert_entry(conn: &Connection, entry: &Entry) -> rusqlite::Result<usize> {
    conn.execute("\
    INSERT INTO Entries (Title, Content)
        VALUES (?1, ?2)
    ",
    &[&entry.title, &entry.content])
}

fn all_entries(conn: &Connection) -> rusqlite::Result<Vec<Entry>> {
    let mut stmt = conn
        .prepare("SELECT ID, Title, Content FROM Entries")?;
    let entry_iter = stmt.query_map(
        NO_PARAMS,
        |row| Ok(Entry{
            id: row.get(0)?,
            title: row.get(1)?,
            content: row.get(2)?
        })
    )?;

    let mut entries = Vec::new();
    for entry in entry_iter {
        entries.push(entry?);
    }

    Ok(entries)
}

fn main() -> rusqlite::Result<()> {
    let conn = Connection::open("db.sqlite")?;
    conn.execute("\
    CREATE TABLE IF NOT EXISTS Entries(
              ID INTEGER PRIMARY KEY,
              Title CHAR(512),
              Content TEXT);
    ",
    NO_PARAMS)?;

    let entry_1 = Entry {
        id: 0,
        title: String::from("Entry Number One"),
        content: String::from("This is the text for my entry.")
    };

    let entry_2 = Entry {
        id: 1,
        title: String::from("Le Second Entreee"),
        content: String::from("2. What is 2? Can you taste it?")
    };

    insert_entry(&conn,&entry_1)?;
    insert_entry(&conn,&entry_2)?;



    println!("{:?}", all_entries(&conn));

    Ok(())
}
/Users/emccue/.cargo/bin/cargo run --color=always --package sequel --bin sequel
   Compiling sequel v0.1.0 (/Users/emccue/Development/sequel)
    Finished dev [unoptimized + debuginfo] target(s) in 1.63s
     Running `target/debug/sequel`
Ok([Entry { id: 1, title: "Entry Number One", content: "This is the text for my entry." }, Entry { id: 2, title: "Le Second Entreee", content: "2. What is 2? Can you taste it?" }])

Process finished with exit code 0

that's gonna take a long time to understand for me

im still in ch one in the rust tutorial

That's fair. C is definitely a simpler language in terms of number of concepts you need to understand.


<- Index