Multidimensional array with unknown items - c

#include <stdio.h>
#include <stdlib.h>
int main() {
int *width;
int *height;
int row;
int column;
int character;
int count;
int pictureit;
double i = 0;
FILE *fp;
char file[50];
char line[25]; // assume each line has max 25 characters
printf("What file should we pull from: ");
scanf("%s", file);
//read file using File pointer
fp = fopen(file, "r");
// read the first line in the file
fgets(line, sizeof(line), fp);
width = strtok(line,"x");
height = strtok(NULL, "/0");
// read all the future lines in the file excluding the first
while (fgets(line, sizeof(line), fp)) {
row = strtok(line, ",");
column = strtok(NULL, ",");
character = strtok(NULL, ",");
count = strtok(NULL, "/0");
if(i < count) {
**printf("%s", pictureit[row][column] = character);**
i++;
}
}
fclose(fp);
return 0;
}
I'm pulling in a file with this kind of setup
75x53
0,36,.,1
0,37,M,1
1,32,.,1
1,33,:,1
1,34,A,1
1,35,M,2
1,37,O,1
1,38,:,1
2,23,.,1
2,24,:,1
2,25,A,1
2,26,M,5
I've been brainstorming for a while. How would I go about displaying this on the console? It obviously needs to go into a 2d array. The program needs to know the height and width of the array to display a space or character in that spot.
PS: This program will display a picture in the console when finished. The "** **" is where I am working.

You could dynamically allocate a 2d array with the right dimensions (according to your first line), then fill it up with the data from your file and finally print it with two nested for loops.
EDIT: Basically, you would do:
//...
//Create the dynamic array
char ** array = malloc(sizeof(char) * height);
int i;
for(i = 0; i < height; i++)
array[i] = malloc(sizeof(char) * width);
// Fill your array here (put different chars in it) ...
//Print it
int x,y;
for(y = 0; y < height; y++)
{
for(x = 0; x < width; x++)
printf("%c ", array[y][x]);
printf("\n");
}
//Free the array
for(i = 0; i < height; i++)
free(array[i]);
free(array);
I voluntarily omitted the part where you check the return value of the malloc (whether it's NULL or not), but you should definitely add it.

Normally I wouldn't do this, but I felt the need to do a scanning exercise:
int main(void)
{
char fn[100];
fprintf(stdout, "Enter file name:");
fflush(stdout);
int result = fscanf(stdin, " %99s", fn);
if (1 != result)
{
fprintf(stderr, "Reading the file's name failed.\n");
exit(EXIT_FAILURE);
}
{
size_t width= 0;
size_t height 0;
FILE * pf = fopen(fn, "r");
if (NULL == pf)
{
fprintf(stderr, "Opening file '%s' failed.\n", fn);
exit(EXIT_FAILURE);
}
{
result = fscanf(pf, " %zux%zu", &width, &height);
if (2 != result)
{
fprintf(stderr, "Reading width and/or heigth from file '%s' failed.\n", fn);
exit(EXIT_FAILURE);
}
{
char (*pa)[width][height] = calloc(1, sizeof *pa);
if (NULL == pa)
{
perror("calloc() failed");
exit(EXIT_FAILURE);
}
{
size_t number_of_rows = width * height;
fprintf(stderr, "Trying to read %zu data rows.\n", number_of_rows);
for (size_t row = 0; row < number_of_rows; ++row)
{
size_t x, y;
char c;
int i;
result = fscanf(pf, " %zu,%zu,%c,%d", &x, &y, &c, &i);
if (4 != result)
{
fprintf(stderr, "Reading data (#%zu) row from '%s' failed.\n", row, fn);
exit(EXIT_FAILURE);
}
/* Add check here to avoid accessing the array out-of-bounds! */
(*pa)[x][y] = c;
}
}
{
for (size_t row = 0; row < width; ++row)
{
for (size_t column = 0; column < height; ++column)
{
fprintf(stdout, "%c", (*pa)[row][column]);
}
fprintf(stdout, "\n");
}
}
free(pa);
}
}
fclose(pf);
}
return EXIT_SUCCESS;
}
Also I am curious about the picture to be printed ... ;-)

Related

C - Sorting a dynamically sized array of strings

I'm quite new to C and trying to read an input stream of data from a file, appending it to a dynamically sized array, which works well to that point.
After that, I want to sort the array alphabetically. I read the manpages of strcmp and think it's the best way to do this. However, I get hit by a "Segmentation Fault" whenever i'm trying to execute it. What exactly am I doing wrong when allocating the memory?
Here is my code for reference:
int main (int argc, char* argv[]) {
int c = getLineCount();
FILE * wordlist = fopen("test", "r");
// If file doesn't exist, handle error
if ( wordlist == NULL ) {
fputs("Unable to open input file", stderr);
exit(1);
}
int length = 101;
char line[length];
int i = 0;
char **words = malloc(c * sizeof(line));
if ( words == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
while (1) {
char *l = fgets(line, length, wordlist);
if ( (l == NULL) ) {
// Check if EOF is reached
if (feof(wordlist)) {
// fputs("--- EOF ---\n", stdout);
break;
// Check if error occured while reading
} else {
fputs("Error reading file", stderr);
exit(1);
}
} else if (strchr(line, '\n') == NULL) {
// Check if line is too long
// Iterate until newline is found or until EOF
int c;
while((c = fgetc(wordlist)) != '\n' && c != 0);
fputs("--- LINE TOO LONG ---\n", stderr);
continue;
} else if ( line[0] == '\n' ) {
// Check if line is only "\n", if yes, ignore the line
continue;
} else {
words[i] = malloc(sizeof(line) * sizeof(char));
if ( words[i] == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
strcpy(words[i], line);
i++;
}
}
// Close file
fclose(wordlist);
char temp[101];
for (int i = 0; i < (length-1); i++) {
int lowest = i;
for (int j = i+1; j < length; j++) {
if (strcmp(words[j], words[lowest]) < 0) {
lowest = j;
}
}
if (lowest != i) {
strcpy(temp, words[i]);
words[i] = words[lowest];
free(words[lowest]);
words[lowest] = malloc(sizeof(temp) * sizeof(char));
if ( words[lowest] == NULL ) {
fputs("Unable to allocate Memory", stderr);
exit(1);
}
strcpy(words[lowest], temp);
}
}
// Print out array
fputs("--- ARRAY ---\n\n", stdout);
for (int i = 0; i < c; i++) {
fputs(words[i], stdout);
}
exit(0);
}
The upper bounds of the sorting algorithm is length, which is incorrect, as length is the size of the input line buffer.
for (int i = 0; i < (length-1); i++) {
The upper bounds should be i from the outer scope here, as it is incremented when a new line is added to the array:
strcpy(words[i], line);
i++;
This upper bounds
for (int i = 0; i < c; i++) {
should be changed as as well, as the number of valid lines might not match the number of expected lines.
Don't forget to free your memory after you are done with it.
These two lines quickly create a memory leak (original pointer value of words[i] is lost), and then set up a use-after-free bug, since the new value of words[i] is the same pointer value as words[lowest], which is freed.
words[i] = words[lowest];
free(words[lowest]);
There is no need for the extra buffer, the (de)allocations, and the string copying here. Just swap the pointer values like you would if you were sorting an array of integers, for example.
char *tmp = words[i];
words[i] = words[lowest];
words[lowest] = tmp;
Here is a common cursory example, without error handling, using strdup. It should illustrate swapping pointer values, and determining the length of the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 256
int main(void) {
char line[4096];
char **lines = malloc(sizeof *lines * MAX_LINES);
size_t len = 0;
while (len < MAX_LINES && fgets(line, sizeof line, stdin))
lines[len++] = strdup(line);
for (size_t i = 0; i < len - 1; i++) {
size_t lowest = i;
for (size_t j = i + 1; j < len; j++)
if (strcmp(lines[j], lines[lowest]) < 0)
lowest = j;
if (lowest != i) {
char *tmp = lines[i];
lines[i] = lines[lowest];
lines[lowest] = tmp;
}
}
for (size_t i = 0; i < len; i++) {
printf("%s", lines[i]);
free(lines[i]);
}
free(lines);
}
stdin:
one
two
hello
foo
world
^D
stdout:
foo
hello
one
two
world

My matrix vector multiplication is returning incorrect values

After digging deep into the internet I managed to read all the numbers in my csv to a matrix vector and also for the other single dimension vector from its related csv. The matrix csv file contains a matrix in the following format
91,86,94
12,54,88
79,58,66
The other input vector file contains the members of the one dimension vector as follows
14
20
22
So I expect the output Vector as a result of this multiplication to be for the first row as
91*14+86*20+94*22=5062
Instead of the above my C code is giving me an insane -1469150284 as the member of the first row of the resultant Vector, I suspected the initialization of the two dimension matrix at first but then even after using memset() to set all elements in the array to 0, I still get the same incorrect values.
The complete code on how I read the csvs and how I load each number into the arrays and how I multiply is provided below, help me trace the bug that is causing the multiplication error
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
//define the three files for reading
FILE *matFile = fopen("test1_input_mat.csv", "r");
FILE *vecFile = fopen("test1_input_vec.csv", "r");
//we are writing to the below file
FILE *outFile = fopen("test1_out_vec.csv", "w");
//make sure the file exists
if (matFile == NULL) {
printf("%s","File does not exist");
//break and return an exit code to the operating system
return 99;
}
//define the dimensions of the matrix
int x = 3;
int y = 3;
//allocate memory to the matrix dynamically
int (*matrix_array)[x] = malloc(sizeof(int[x][y]));
//initialize all the members to zero
memset(matrix_array, 0, sizeof(matrix_array));
//read from the matFile and assign to the vector
char *r, l;
//create a buffer variable for the read file process
char buffer[255];
char line[255] = "";
char *replaced = NULL;
while (fgets(buffer, sizeof(buffer), matFile)) {
strncat(line, buffer, 255);
}
// printf("%s",line);
replaced = replaceWord(line, "\n", ",");
//printf("%s", replaced);
//now that we have the elements of the file in a line
//separated by commas
char delim[] = ",";
char *token;
//get the first token
token = strtok(replaced, delim);
//walk through other tokens
while (token != NULL) {
//parse this and add it to the array
int sub = atoi(token);
//assign the number to th array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
matrix_array[i][j] = sub;
}
}
token = strtok(NULL, delim);
}
//allocate memory to one dimension array
int *vec = (int *)malloc(3 * sizeof(int));
//section below handles the parsing of numbers from the vector file
char vline[255] = "";
char vbuffer[255];
char concatenated[255];
char *replacing;
//read the vector file
while (fgets(vbuffer, 255, vecFile)) {
strncat(concatenated, vbuffer, sizeof(vbuffer));
}
//replace the new line characters with commas
replacing = replaceWord(concatenated, "\n", ",");
//now parse that into the one dimension vector
char *vtoken;
//get the first token
vtoken = strtok(replacing, delim);
//get the rest of the tokens
while (vtoken != NULL) {
int no = atoi(vtoken);
//append the numbers to the one dimension vector
for (int i = 0; i < 3; i++) {
vec[i] = no;
}
vtoken = strtok(NULL, delim);
}
//this is the section where we do the multiplication of the two
int *out_vec = (int *)malloc(3 * sizeof(int));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//assign the product of the multiplication to the right index in the vector
out_vec[j] += matrix_array[i][j] * vec[j];
}
}
//write the integers in the second to the out file
char str[255];
char fin[255];
for (int i = 0; i < 3; i++) {
printf("%d\n", out_vec[i]);
}
//close the matFile
fclose(matFile);
}
//method to replace the newline characters with commas
This code helped me replace the new line characters with commas in the single line comprised of all lines in the file
//this method replaces a string in the target string with another string
char *replaceWord(const char *s, const char *oldW,
const char *newW)
{
char *result;
int i, cnt = 0;
int newWlen = strlen(newW);
int oldWlen = strlen(oldW);
// Counting the number of times old word
// occur in the string
for (i = 0; s[i] != '\0'; i++) {
if (strstr(&s[i], oldW) == &s[i]) {
cnt++;
// Jumping to index after the old word.
i += oldWlen - 1;
}
}
// Making new string of enough length
result = (char *)malloc(i + cnt * (newWlen - oldWlen) + 1);
i = 0;
while (*s) {
// compare the substring with the result
if (strstr(s, oldW) == s) {
strcpy(&result[i], newW);
i += newWlen;
s += oldWlen;
} else
result[i++] = *s++;
}
result[i] = '\0';
return result;
}
I have tried to simplify and clean up your code as much as possible.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 3
#define COLS 3
int main(int argc, char* argv[])
{
FILE* matFile = fopen("test1_input_mat.csv", "r");
if (!matFile) {
puts("File does not exist");
return 99;
}
int (*matrix_array)[ROWS] = malloc(sizeof(int[ROWS][COLS]));
char buffer[255];
for (int row = 0; row < ROWS; row++) {
if (fgets(buffer, sizeof(buffer), matFile)) {
char *p = strtok(buffer, ",");
for (int col = 0; col < COLS; col++) {
if (!p) return 99;
matrix_array[row][col] = atoi(p);
p = strtok(NULL, ",");
}
}
}
fclose(matFile);
FILE* vecFile = fopen("test1_input_vec.csv", "r");
if (!vecFile) {
puts("File does not exist");
return 99;
}
int* vec = malloc(ROWS * sizeof(int));
for (int row = 0; row < ROWS; row++) {
if (fscanf(vecFile, "%d", &vec[row]) != 1) return 99;
}
fclose(vecFile);
int* out_vec = calloc(ROWS, sizeof(int));
for (int row = 0; row < ROWS; row++){
for (int col = 0; col < COLS; col++){
out_vec[row] += matrix_array[row][col] * vec[col];
}
}
for (int row = 0; row < ROWS; row++){
printf("%d\n", out_vec[row]);
}
free(matrix_array);
free(vec);
free(out_vec);
return 0;
}
One thing still to do is check the return values from malloc and calloc. Though it is unlikely in a small program like this, they can return NULL
Also, since you have hard-coded the size to be 3x3, there is no need for malloc/calloc.
#define ROWS 3
#define COLS 3
...
int matrix_array[ROWS][COLS];
int vec[ROWS];
int out_vec[ROWS] = {0}

C Programming - Selection Sort from File (Run Failed)

I have to write a program that sorts quotes by length in a text file and outputs the result to another file. But while the compile works and builds with no error, I still get unexpected results, plus a run error in netbeans:
void read_in(char** quotes, size_t* size){
*size = 0;
FILE *filePointer;
filePointer = fopen("quotes.txt", "r");
if (filePointer == NULL){
perror("Error: File cannot be opened! \n");
exit(1);
}
char tempArr[MAX_LEN];
while(fgets(tempArr, sizeof(tempArr), filePointer)){
if(*size == MAX_QUOTES){
printf("Warning: File contains more than 7 quotes. Load halted. \n");
return;
}
char* ptrMem = (char*)malloc(sizeof(char) * strlen(tempArr));
if(!ptrMem){
printf("Error: Memory could not be allocated! \n");
return;
}
strcpy(ptrMem, tempArr);
ptrMem[strcspn(ptrMem, "\n")] = '\r';
quotes[(*size)++] = ptrMem;
}
fclose(filePointer);
}
//-----------------------------------------------------------------------------------------------
void selection_sort(char **quotes, size_t size){
// Current min value to compare
int minValue;
printf("--- Input:\n");
// Loop and print quotes from array
for(int i = 0; i < (size - 1); i++){
printf("%s\n", quotes[i]);
}
for(int i = 0; i < (size - 1); i++){
// Determine minimum element
minValue = i ;
for(int j = i + 1; j < size; j++) {
if(strlen(quotes[j]) < strlen(quotes[minValue])){
minValue = j;
}
swap(&quotes[minValue], &quotes[i]);
}
}
}
//-----------------------------------------------------------------------------------------------
void print_out(char** quotes, size_t size){
printf("--- Output:\n");
for (int i = 0; i < size; i++){
printf("%s\n", quotes[i]);
}
}
//-----------------------------------------------------------------------------------------------
void write_out(char** quotes, size_t size){
FILE *filePointer = fopen("output.txt", "w");
// If file ptr null value, throw exception
if (filePointer == NULL){
perror("Error: Cannot write to file!");
exit(1);
}
for (int i = 0; i < size; i++){
fprintf(filePointer, "%s\n", quotes[i]);
}
// Close file ptr after use
fclose(filePointer);
}
//-----------------------------------------------------------------------------------------------
void free_memory(char** quotes, size_t size){
// Loop through array of quotes (pointers) and free each allocation
for (int i = 0; i < size ;i++){
free(quotes[i]);
}
}
//-----------------------------------------------------------------------------------------------
void swap(char **quote_A, char **quote_B){
char *temp = *quote_B;
*quote_A = *quote_B;
*quote_A = temp;
}
This is what I get in ouput:
For some reason, it's repeating a string (char pointer quote) over and over. What it's supposed to do is have them sorted by length which is what my selection_sort algorithm was supposed to do. All the function prototypes were defined above that code. I figured it would take too much space to put the entire program, but I can if needed.
Also, the main method and header files are defined above.
EDIT: I do get some warning about strcpy not being able to be limited to a max buffer size

Line from file isn't reading after using pointer inside the loop

So I am trying to read a matrix from a file (I am sure there are better ways to do it than how I am doing it). I had a hard time figuring out how to read each word from the file (meaning each entry of the matrix) so decided to read each line and use something I found here in stackexchange called strtok.
The inside of my main() looks like this
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
#include <string.h>
int main(){
FILE *f;
int nmatrix=3;
int nmax=3;
int something;
int number, count, count2, i, j;
srand(time(NULL));
size_t len = 0;
ssize_t read;
char * line = NULL;
char * pch;
int ia;
int (*B)[nmatrix][nmatrix] = malloc(nmatrix * nmatrix * sizeof(int));
while(nmatrix<=nmax){
// Creation of Matrix
f = fopen("matrix.txt", "w");
for(count = 1; count <= nmatrix; count ++){
for(count2 = 1; count2 <= nmatrix; count2 ++){
number = rand()%9;
fprintf(f, "%s%d ", " ", number);
}
fprintf(f, "%s\n", " ");
}
fclose(f);
// Reading Matrix
f = fopen("matrix.txt", "r");
i=0;
while((read = getline(&line, &len, f)) != -1) {
printf("%s\n", line);
pch = strtok(line," ,.-");
j=0;
while (pch != NULL & j<nmatrix){
ia= (int)*pch-48;
*B[i][j]= ia;
pch = strtok(NULL, " ,.-");
j=j+1;
}
i=i+1;
}
fclose(f);
nmatrix=nmatrix+1;
}
return 0;
}
The first output in terminal is if the line *B[i][j]= ia; is erased, and the second with it. The first ouput reads all the lines in the file and the second doesnt read the last. Why? (The output looks different cuz the matrices are generated at random).
Thanks in advance
I am fairly new to everything, specially pointers so if anything is not used correctly I'd appreciate the comment.
You had a couple of issues. You were using & instead of && (not really affecting it, but still wrong) and you had your pointer wrong in the assignment. I changed the output to display what is stored in the matrix, instead of the read line.
*B[i][j]= ia; needs to be (*B)[i][j]= ia;
// Reading Matrix
f = fopen("matrix.txt", "r");
i=0;
while((read = getline(&line, &len, f)) != -1) {
pch = strtok(line," ,.-");
j=0;
while (pch != NULL && j<nmatrix){
printf("\n%d %d :", i, j);
ia= (int)*pch-48;
(*B)[i][j]= ia;
printf("%d\n", (*B)[i][j]);
pch = strtok(NULL," ,.-");
j=j+1;
}
i=i+1;
}
fclose(f);
You have a lot of errors:
your string to break the numbers os the matrix are not inserted when you create the matrix: " ,.-". These must be inserted to be used in strtok function.
should be && instead of & in while statement
you have an extra } at the end of file.
both whiles to create the matrix should start at 0 and go to nmatrix with < symbol.
you should initialize the string line with "", not null.
int main(){
FILE *f;
int nmatrix=3;
int nmax=3;
int number, count, count2, i, j;
srand(time(NULL));
size_t len = 0;
ssize_t read;
char * line = "";
char * pch;
int ia;
int (*B)[nmatrix][nmatrix] = malloc(nmatrix * nmatrix * sizeof(int));
while(nmatrix<=nmax){
// Creation of Matrix
f = fopen("matrix.txt", "w");
for(count = 0; count < nmatrix; count ++){
for(count2 = 0; count2 < nmatrix; count2 ++){
number = rand()%9;
fprintf(f, "%s%d ", " ", number);
}
fprintf(f, "%s\n", " ");
}
fclose(f);
// Reading Matrix
f = fopen("matrix.txt", "r");
i=0;
while((read = getline(&line, &len, f)) != -1) {
printf("%s\n", line);
pch = strtok(line," ");
j=0;
while (pch != NULL && j < nmatrix){
ia= (int)*pch-48;
*B[i][j]= ia;
pch = strtok(NULL, " ");
j=j+1;
}
i=i+1;
}
fclose(f);
nmatrix=nmatrix+1;
}
return 0;
}

Parsing .csv file into 2D array in C

I have a .csv file that reads like:
SKU,Plant,Qty
40000,ca56,1245
40000,ca81,12553.3
40000,ca82,125.3
45000,ca62,0
45000,ca71,3
45000,ca78,54.9
Note: This is my example but in reality this has about 500,000 rows and 3 columns.
I am trying to convert these entries into a 2D array so that I can then manipulate the data. You'll notice that in my example I just set a small 10x10 matrix A to try and get this example to work before moving on to the real thing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *getfield(char *line, int num);
int main() {
FILE *stream = fopen("input/input.csv", "r");
char line[1000000];
int A[10][10];
int i, j = 0;
//Zero matrix
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
A[i][j] = 0;
}
}
for (i = 0; fgets(line, 1000000, stream); i++) {
while (j < 10) {
char *tmp = strdup(line);
A[i][j] = getfield(tmp, j);
free(tmp);
j++;
}
}
//print matrix
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
printf("%s\t", A[i][j]);
}
printf("\n");
}
}
const char *getfield(char *line, int num) {
const char *tok;
for (tok = strtok(line, ",");
tok && *tok;
tok = strtok(NULL, ",\n"))
{
if (!--num)
return tok;
}
return 0;
}
It prints only "null" errors, and it is my belief that I am making a mistake related to pointers on this line: A[i][j] = getfield(tmp, j). I'm just not really sure how to fix that.
This is work that is based almost entirely on this question: Read .CSV file in C . Any help in adapting this would be very much appreciated as it's been a couple years since I last touched C or external files.
It looks like commenters have already helped you find a few errors in your code. However, the problems are pretty entrenched. One of the biggest issues is that you're using strings. Strings are, of course, char arrays; that means that there's already a dimension in use.
It would probably be better to just use a struct like this:
struct csvTable
{
char sku[10];
char plant[10];
char qty[10];
};
That will also allow you to set your columns to the right data types (it looks like SKU could be an int, but I don't know the context).
Here's an example of that implementation. I apologize for the mess, it's adapted on the fly from something I was already working on.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Based on your estimate
// You could make this adaptive or dynamic
#define rowNum 500000
struct csvTable
{
char sku[10];
char plant[10];
char qty[10];
};
// Declare table
struct csvTable table[rowNum];
int main()
{
// Load file
FILE* fp = fopen("demo.csv", "r");
if (fp == NULL)
{
printf("Couldn't open file\n");
return 0;
}
for (int counter = 0; counter < rowNum; counter++)
{
char entry[100];
fgets(entry, 100, fp);
char *sku = strtok(entry, ",");
char *plant = strtok(NULL, ",");
char *qty = strtok(NULL, ",");
if (sku != NULL && plant != NULL && qty != NULL)
{
strcpy(table[counter].sku, sku);
strcpy(table[counter].plant, plant);
strcpy(table[counter].qty, qty);
}
else
{
strcpy(table[counter].sku, "\0");
strcpy(table[counter].plant, "\0");
strcpy(table[counter].qty, "\0");
}
}
// Prove that the process worked
for (int printCounter = 0; printCounter < rowNum; printCounter++)
{
printf("Row %d: column 1 = %s, column 2 = %s, column 3 = %s\n",
printCounter + 1, table[printCounter].sku,
table[printCounter].plant, table[printCounter].qty);
}
// Wait for keypress to exit
getchar();
}
There are multiple problems in your code:
In the second loop, you do not stop reading the file after 10 lines, so you would try and store elements beyond the end of the A array.
You do not reset j to 0 at the start of the while (j < 10) loop. j happens to have the value 10 at the end of the initialization loop, so you effectively do not store anything into the matrix.
The matrix A should be a 2D array of char *, not int, or potentially an array of structures.
Here is a simpler version with an allocated array of structures:
#include <stdio.h>
#include <stdlib.h>
typedef struct item_t {
char SKU[20];
char Plant[20];
char Qty[20];
};
int main(void) {
FILE *stream = fopen("input/input.csv", "r");
char line[200];
int size = 0, len = 0, i, c;
item_t *A = NULL;
if (stream) {
while (fgets(line, sizeof(line), stream)) {
if (len == size) {
size = size ? size * 2 : 1000;
A = realloc(A, sizeof(*A) * size);
if (A == NULL) {
fprintf(stderr, "out of memory for %d items\n", size);
return 1;
}
}
if (sscanf(line, "%19[^,\n],%19[^,\n],%19[^,\n]%c",
A[len].SKU, A[len].Plant, A[len].Qty, &c) != 4
|| c != '\n') {
fprintf(stderr, "invalid format: %s\n, line);
} else {
len++;
}
}
fclose(stream);
//print matrix
for (i = 0; i < len; i++) {
printf("%s,%s,%s\n", A[i].SKU, A[i].Plant, A[i].Qty);
}
free(A);
}
return 0;
}

Resources