Dynamic 2D array in C not reading first element












0















My uni tasked me with writing a program that reads the input and stores it into a dynamic 2D array, but we haven't covered that topic. I'm encountering a problem with my implementation, as it is skipping the first character in each line. I know the code is not top quality, but I just can't figure out why it skips the first char.



#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


#define MULT 3
#define DIV 2

char *read_line(int *col_size, int *max_c) {
char *line = NULL;
int size = *col_size;
int i, c;
line = malloc(size * sizeof *line);
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if (i == size) {
size = 1 + size * MULT / DIV;
line = realloc(line, size * sizeof *line);
assert(line != NULL);
}
line[i] = c;
}
if (i > *max_c)
*max_c = i;
if (size > *col_size)
*col_size = size;
return line;
}

char **read(int *row, int *col) {
char **input = NULL;
int row_size = 0;
int col_size = 0;
int i, c;
int max_c = 0;

for (i = 0; (c = getchar()) != EOF; ++i) {
if (i == row_size) {
row_size = 1 + row_size * MULT / DIV;
input = realloc(input, row_size * sizeof *input);
assert(input != NULL);
}
input[i] = read_line(&col_size, &max_c);
}
*row = i;
*col = max_c;
return input;
}


int main(void) {
int row_size, col_size, i, j;
char **board = read(&row_size, &col_size);
for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]);
putchar('n');
}
free(board);
return 0;
}









share|improve this question























  • I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

    – whoasked
    Nov 22 '18 at 16:58






  • 4





    @whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

    – Thomas Jager
    Nov 22 '18 at 17:08
















0















My uni tasked me with writing a program that reads the input and stores it into a dynamic 2D array, but we haven't covered that topic. I'm encountering a problem with my implementation, as it is skipping the first character in each line. I know the code is not top quality, but I just can't figure out why it skips the first char.



#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


#define MULT 3
#define DIV 2

char *read_line(int *col_size, int *max_c) {
char *line = NULL;
int size = *col_size;
int i, c;
line = malloc(size * sizeof *line);
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if (i == size) {
size = 1 + size * MULT / DIV;
line = realloc(line, size * sizeof *line);
assert(line != NULL);
}
line[i] = c;
}
if (i > *max_c)
*max_c = i;
if (size > *col_size)
*col_size = size;
return line;
}

char **read(int *row, int *col) {
char **input = NULL;
int row_size = 0;
int col_size = 0;
int i, c;
int max_c = 0;

for (i = 0; (c = getchar()) != EOF; ++i) {
if (i == row_size) {
row_size = 1 + row_size * MULT / DIV;
input = realloc(input, row_size * sizeof *input);
assert(input != NULL);
}
input[i] = read_line(&col_size, &max_c);
}
*row = i;
*col = max_c;
return input;
}


int main(void) {
int row_size, col_size, i, j;
char **board = read(&row_size, &col_size);
for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]);
putchar('n');
}
free(board);
return 0;
}









share|improve this question























  • I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

    – whoasked
    Nov 22 '18 at 16:58






  • 4





    @whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

    – Thomas Jager
    Nov 22 '18 at 17:08














0












0








0








My uni tasked me with writing a program that reads the input and stores it into a dynamic 2D array, but we haven't covered that topic. I'm encountering a problem with my implementation, as it is skipping the first character in each line. I know the code is not top quality, but I just can't figure out why it skips the first char.



#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


#define MULT 3
#define DIV 2

char *read_line(int *col_size, int *max_c) {
char *line = NULL;
int size = *col_size;
int i, c;
line = malloc(size * sizeof *line);
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if (i == size) {
size = 1 + size * MULT / DIV;
line = realloc(line, size * sizeof *line);
assert(line != NULL);
}
line[i] = c;
}
if (i > *max_c)
*max_c = i;
if (size > *col_size)
*col_size = size;
return line;
}

char **read(int *row, int *col) {
char **input = NULL;
int row_size = 0;
int col_size = 0;
int i, c;
int max_c = 0;

for (i = 0; (c = getchar()) != EOF; ++i) {
if (i == row_size) {
row_size = 1 + row_size * MULT / DIV;
input = realloc(input, row_size * sizeof *input);
assert(input != NULL);
}
input[i] = read_line(&col_size, &max_c);
}
*row = i;
*col = max_c;
return input;
}


int main(void) {
int row_size, col_size, i, j;
char **board = read(&row_size, &col_size);
for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]);
putchar('n');
}
free(board);
return 0;
}









share|improve this question














My uni tasked me with writing a program that reads the input and stores it into a dynamic 2D array, but we haven't covered that topic. I'm encountering a problem with my implementation, as it is skipping the first character in each line. I know the code is not top quality, but I just can't figure out why it skips the first char.



#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


#define MULT 3
#define DIV 2

char *read_line(int *col_size, int *max_c) {
char *line = NULL;
int size = *col_size;
int i, c;
line = malloc(size * sizeof *line);
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if (i == size) {
size = 1 + size * MULT / DIV;
line = realloc(line, size * sizeof *line);
assert(line != NULL);
}
line[i] = c;
}
if (i > *max_c)
*max_c = i;
if (size > *col_size)
*col_size = size;
return line;
}

char **read(int *row, int *col) {
char **input = NULL;
int row_size = 0;
int col_size = 0;
int i, c;
int max_c = 0;

for (i = 0; (c = getchar()) != EOF; ++i) {
if (i == row_size) {
row_size = 1 + row_size * MULT / DIV;
input = realloc(input, row_size * sizeof *input);
assert(input != NULL);
}
input[i] = read_line(&col_size, &max_c);
}
*row = i;
*col = max_c;
return input;
}


int main(void) {
int row_size, col_size, i, j;
char **board = read(&row_size, &col_size);
for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]);
putchar('n');
}
free(board);
return 0;
}






c






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 22 '18 at 16:54









gubenguben

185




185













  • I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

    – whoasked
    Nov 22 '18 at 16:58






  • 4





    @whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

    – Thomas Jager
    Nov 22 '18 at 17:08



















  • I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

    – whoasked
    Nov 22 '18 at 16:58






  • 4





    @whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

    – Thomas Jager
    Nov 22 '18 at 17:08

















I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

– whoasked
Nov 22 '18 at 16:58





I've really only glanced at your code, but the one thing jumps out is you have ++i, not i++ in your for loops.

– whoasked
Nov 22 '18 at 16:58




4




4





@whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

– Thomas Jager
Nov 22 '18 at 17:08





@whoasked It doesn't matter which one is used because that statement's value doesn't matter. It's not uncommon to use ++i because it may be slightly more efficient on some systems, depending on optimizations.

– Thomas Jager
Nov 22 '18 at 17:08












1 Answer
1






active

oldest

votes


















1















for (i = 0; (c = getchar()) != EOF; ++i) {



in read() eats up the first character of a line before read_line() gets to see it. You'll have to find some other way to check for EOF. For example with



for (i = 0; !feof(stdin); ++i) {




Also, you don't zero-terminate your strings. Change your reading loop to



char *read_line(int *col_size, int *max_c) {
int size = *col_size ? *col_size : 1; // at least 1 for the terminating 0
char *line = malloc(size * sizeof *line);

if(!line)
return NULL;

int i, c;
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if(i == size) {
size = 2 + size * MULT / DIV; // note the 2
// ...
}
// ...
}
line[i] = '';


to do so.






for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]); // accesses memory that isn't yours
putchar('n'); // if not all rows are of the same length.
}



To avoid reading memory out-of-bounds, change that to



for (i = 0; i < row_size; ++i) {
for (j = 0; board[i][j] != ''; ++j)
putchar(board[i][j]);
putchar('n');
}


since you now have zero-terminated strings. Or why not just use puts()?



for (i = 0; i < row_size; ++i)
puts(board[i]);





free(board);



That won't deallocate the memory you allocated for the rows. You'd have to



for (i = 0; i < row_size; ++i)
free(bard[i]);
free(board);





share|improve this answer


























  • Thank you so much! I see there's a lot I have to learn yet ;)))

    – guben
    Nov 22 '18 at 20:04











  • Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

    – guben
    Nov 22 '18 at 20:14











  • @guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

    – Swordfish
    Nov 22 '18 at 20:19













  • From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

    – guben
    Nov 22 '18 at 20:37













  • Actually, Valgrind throws an invalid write error, when given an empty row :/

    – guben
    Nov 22 '18 at 21:11











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435425%2fdynamic-2d-array-in-c-not-reading-first-element%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1















for (i = 0; (c = getchar()) != EOF; ++i) {



in read() eats up the first character of a line before read_line() gets to see it. You'll have to find some other way to check for EOF. For example with



for (i = 0; !feof(stdin); ++i) {




Also, you don't zero-terminate your strings. Change your reading loop to



char *read_line(int *col_size, int *max_c) {
int size = *col_size ? *col_size : 1; // at least 1 for the terminating 0
char *line = malloc(size * sizeof *line);

if(!line)
return NULL;

int i, c;
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if(i == size) {
size = 2 + size * MULT / DIV; // note the 2
// ...
}
// ...
}
line[i] = '';


to do so.






for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]); // accesses memory that isn't yours
putchar('n'); // if not all rows are of the same length.
}



To avoid reading memory out-of-bounds, change that to



for (i = 0; i < row_size; ++i) {
for (j = 0; board[i][j] != ''; ++j)
putchar(board[i][j]);
putchar('n');
}


since you now have zero-terminated strings. Or why not just use puts()?



for (i = 0; i < row_size; ++i)
puts(board[i]);





free(board);



That won't deallocate the memory you allocated for the rows. You'd have to



for (i = 0; i < row_size; ++i)
free(bard[i]);
free(board);





share|improve this answer


























  • Thank you so much! I see there's a lot I have to learn yet ;)))

    – guben
    Nov 22 '18 at 20:04











  • Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

    – guben
    Nov 22 '18 at 20:14











  • @guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

    – Swordfish
    Nov 22 '18 at 20:19













  • From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

    – guben
    Nov 22 '18 at 20:37













  • Actually, Valgrind throws an invalid write error, when given an empty row :/

    – guben
    Nov 22 '18 at 21:11
















1















for (i = 0; (c = getchar()) != EOF; ++i) {



in read() eats up the first character of a line before read_line() gets to see it. You'll have to find some other way to check for EOF. For example with



for (i = 0; !feof(stdin); ++i) {




Also, you don't zero-terminate your strings. Change your reading loop to



char *read_line(int *col_size, int *max_c) {
int size = *col_size ? *col_size : 1; // at least 1 for the terminating 0
char *line = malloc(size * sizeof *line);

if(!line)
return NULL;

int i, c;
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if(i == size) {
size = 2 + size * MULT / DIV; // note the 2
// ...
}
// ...
}
line[i] = '';


to do so.






for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]); // accesses memory that isn't yours
putchar('n'); // if not all rows are of the same length.
}



To avoid reading memory out-of-bounds, change that to



for (i = 0; i < row_size; ++i) {
for (j = 0; board[i][j] != ''; ++j)
putchar(board[i][j]);
putchar('n');
}


since you now have zero-terminated strings. Or why not just use puts()?



for (i = 0; i < row_size; ++i)
puts(board[i]);





free(board);



That won't deallocate the memory you allocated for the rows. You'd have to



for (i = 0; i < row_size; ++i)
free(bard[i]);
free(board);





share|improve this answer


























  • Thank you so much! I see there's a lot I have to learn yet ;)))

    – guben
    Nov 22 '18 at 20:04











  • Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

    – guben
    Nov 22 '18 at 20:14











  • @guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

    – Swordfish
    Nov 22 '18 at 20:19













  • From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

    – guben
    Nov 22 '18 at 20:37













  • Actually, Valgrind throws an invalid write error, when given an empty row :/

    – guben
    Nov 22 '18 at 21:11














1












1








1








for (i = 0; (c = getchar()) != EOF; ++i) {



in read() eats up the first character of a line before read_line() gets to see it. You'll have to find some other way to check for EOF. For example with



for (i = 0; !feof(stdin); ++i) {




Also, you don't zero-terminate your strings. Change your reading loop to



char *read_line(int *col_size, int *max_c) {
int size = *col_size ? *col_size : 1; // at least 1 for the terminating 0
char *line = malloc(size * sizeof *line);

if(!line)
return NULL;

int i, c;
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if(i == size) {
size = 2 + size * MULT / DIV; // note the 2
// ...
}
// ...
}
line[i] = '';


to do so.






for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]); // accesses memory that isn't yours
putchar('n'); // if not all rows are of the same length.
}



To avoid reading memory out-of-bounds, change that to



for (i = 0; i < row_size; ++i) {
for (j = 0; board[i][j] != ''; ++j)
putchar(board[i][j]);
putchar('n');
}


since you now have zero-terminated strings. Or why not just use puts()?



for (i = 0; i < row_size; ++i)
puts(board[i]);





free(board);



That won't deallocate the memory you allocated for the rows. You'd have to



for (i = 0; i < row_size; ++i)
free(bard[i]);
free(board);





share|improve this answer
















for (i = 0; (c = getchar()) != EOF; ++i) {



in read() eats up the first character of a line before read_line() gets to see it. You'll have to find some other way to check for EOF. For example with



for (i = 0; !feof(stdin); ++i) {




Also, you don't zero-terminate your strings. Change your reading loop to



char *read_line(int *col_size, int *max_c) {
int size = *col_size ? *col_size : 1; // at least 1 for the terminating 0
char *line = malloc(size * sizeof *line);

if(!line)
return NULL;

int i, c;
for (i = 0; ((c = getchar()) != 'n') && (c != EOF); ++i) {
if(i == size) {
size = 2 + size * MULT / DIV; // note the 2
// ...
}
// ...
}
line[i] = '';


to do so.






for (i = 0; i < row_size; ++i) {
for (j = 0; j < col_size; ++j)
putchar(board[i][j]); // accesses memory that isn't yours
putchar('n'); // if not all rows are of the same length.
}



To avoid reading memory out-of-bounds, change that to



for (i = 0; i < row_size; ++i) {
for (j = 0; board[i][j] != ''; ++j)
putchar(board[i][j]);
putchar('n');
}


since you now have zero-terminated strings. Or why not just use puts()?



for (i = 0; i < row_size; ++i)
puts(board[i]);





free(board);



That won't deallocate the memory you allocated for the rows. You'd have to



for (i = 0; i < row_size; ++i)
free(bard[i]);
free(board);






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 20:24

























answered Nov 22 '18 at 17:18









SwordfishSwordfish

9,34811336




9,34811336













  • Thank you so much! I see there's a lot I have to learn yet ;)))

    – guben
    Nov 22 '18 at 20:04











  • Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

    – guben
    Nov 22 '18 at 20:14











  • @guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

    – Swordfish
    Nov 22 '18 at 20:19













  • From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

    – guben
    Nov 22 '18 at 20:37













  • Actually, Valgrind throws an invalid write error, when given an empty row :/

    – guben
    Nov 22 '18 at 21:11



















  • Thank you so much! I see there's a lot I have to learn yet ;)))

    – guben
    Nov 22 '18 at 20:04











  • Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

    – guben
    Nov 22 '18 at 20:14











  • @guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

    – Swordfish
    Nov 22 '18 at 20:19













  • From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

    – guben
    Nov 22 '18 at 20:37













  • Actually, Valgrind throws an invalid write error, when given an empty row :/

    – guben
    Nov 22 '18 at 21:11

















Thank you so much! I see there's a lot I have to learn yet ;)))

– guben
Nov 22 '18 at 20:04





Thank you so much! I see there's a lot I have to learn yet ;)))

– guben
Nov 22 '18 at 20:04













Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

– guben
Nov 22 '18 at 20:14





Altough, it's possible that the program is going to try to place the '' at an index that isn't allocated, since it's outside the loop that checks wether i is small enough.

– guben
Nov 22 '18 at 20:14













@guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

– Swordfish
Nov 22 '18 at 20:19







@guben You are right. size = 1 + size * MULT / DIV; should be size = 2 + size * MULT / DIV; Where does that idea of MULT / DIV come from?

– Swordfish
Nov 22 '18 at 20:19















From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

– guben
Nov 22 '18 at 20:37







From the example code given by my uni professor, who said that usually, it's multiplied by 2, but here it's better to multiply by 3/2. He didn't tell us why though xD

– guben
Nov 22 '18 at 20:37















Actually, Valgrind throws an invalid write error, when given an empty row :/

– guben
Nov 22 '18 at 21:11





Actually, Valgrind throws an invalid write error, when given an empty row :/

– guben
Nov 22 '18 at 21:11


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435425%2fdynamic-2d-array-in-c-not-reading-first-element%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'