Using String Arrays in C - c

I tried to store strings in an array. But there is a mistake. My code is here:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
const long long max_size = 2000; // max length of strings
const long long N = 40; // number of closest words that will be shown
const long long max_w = 50; // max length of vocabulary entries
int main(int argc, char **argv) {
FILE *f;
char st1[max_size];
char kelimeler[max_size];
char *kelimelerim[max_size]; //string array initialization here
char *bestw[N];
char file_name[max_size], st[100][max_size];
float dist, len, bestd[N], vec[max_size];
long long words, size, a, b, c, d, cn, bi[100];
char ch;
float *M;
char *vocab;
strcpy(file_name, argv[1]);
f = fopen(file_name, "rb");
if (f == NULL) {
printf("Input file not found\n");
return -1;
}
fscanf(f, "%lld", &words);
fscanf(f, "%lld", &size);
vocab = (char *)malloc((long long)words * max_w * sizeof(char));
for (a = 0; a < N; a++) bestw[a] = (char *)malloc(max_size * sizeof(char));
M = (float *)malloc((long long)words * (long long)size * sizeof(float));
if (M == NULL) {
printf("Cannot allocate memory");
return -1;
}
for (b = 0; b < words; b++) {
a = 0;
int sayac=0;
while (1) {
sayac++;
vocab[b * max_w + a] = fgetc(f);
if (feof(f) || (vocab[b * max_w + a] == ' ')) {
strcpy(kelimeler,&vocab[b * max_w + a-sayac+2]); //gets the string here
kelimelerim[b] = kelimeler; //and store it into string array here
printf("%s %lld\n",kelimelerim[b],b);
sayac=0;
break;
}
if ((a < max_w) && (vocab[b * max_w + a] != '\n'))
a++;
}
vocab[b * max_w + a] = 0;
for (a = 0; a < size; a++)
fread(&M[a + b * size], sizeof(float), 1, f);
len = 0;
for (a = 0; a < size; a++)
len += M[a + b * size] * M[a + b * size];
len = sqrt(len);
for (a = 0; a < size; a++)
M[a + b * size] /= len;
}
fclose(f);
int index;
for (index = 0; index < words; index ++){
printf("%s %d \n",kelimelerim[index ], index );
}
// here, the loop prints last string stored into array, for all indexes.
I deleted the unimportant rows. When I run the above code and print the kelimelerim array, the last string is printed for all indexes of the array. Where is my mistake? Could you help me, please.

You never initialize vocab, so the following has undefined behaviour:
vocab[b * max_w + a] = fgetc(f);
From that point on, all bets are off.

This
kelimelerim[b] = kelimeler;
does not copy any data, but only stores the address of kelimeler to kelimelerim[b]. If then looping over kelimelerim[b]'s elements, only references to kelimeler are found and as kelimeler gets re-used for each iteration, it contains the string read last, which then in turn is printed for each of element of kelimelerim[b].
Update:
To fix this either replace kelimelerim[b] by an array of "string" not just pointers to strings and do
strcpy(kelimelerim[b], kelimeler);
or dynamically create a real copy of kelimeler by doing:
kelimelerim[b] = strdup(kelimeler);
Be aware that for this latter case each call to strdup() allocates memory from the heap, which you shall free if not used anymore, by calling free() on each elelment of kelimelerim.
Also strdup() isn't Standard C but a POSIX extension. You might need to #define something to have it avaliable. See your implementation's documentaion on strdup() for details.
If strdup() is not available you might like to use this:
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for strcpy() */
#include <errno.h> /* for errno */
char * strdup(const char * s)
{
char * p = NULL;
if (NULL == s)
{
errno = EINVAL;
}
else
{
p = malloc(strlen(s) + 1);
if (NULL == p)
{
errno = ENOMEM;
}
else
{
strcpy(p, s);
}
}
return p;
}

You are using char *vocab; as uninitialized pointer. This results in undefined behavior. You have to initialize this pointer before using it with a valid memory ( e.g. using malloc).

Related

How to modify a char pointer passed as parameter in a function?

So, I am doing my own rudimentary version of itoa(), and I just realized I don't exactly know how to modify a char* passed as parameter, or if there is something wrong with the way I am doing it...
The way I am doing it is by doing malloc() onto the buffer passed as argument, then write the number into it. This is apparently working before returning from the function (the buffer is printed correctly), but then when trying to print it back in main(), it segfaults.
If I understand the error correctly, I am changing the address buff points to inside with that malloc(), and then modify its contents, but the new malloc'd address inside is not returned. How could I do that without changing the parameters or the return value?
int itoa(int i, char *buff) {
int length = 0;
// get the length
long temp = 1;
while (temp <= i) {
length++;
temp *= 10;
}
buff = malloc(length + 1); // buff will have 'length' chars + one extra (\0)
int j = 0;
do { /* generate digits in reverse order */
buff[j++] = i % 10 + '0'; /* get next digit */
} while ((i /= 10) > 0); /* delete it */
buff[length] = '\0';
// reverse it
int k, l;
char c;
for (k = 0, l = length - 1; k<l; k++, l--) {
c = buff[k];
buff[k] = buff[l];
buff[l] = c;
}
printf("buff's now:%s\n", buff);
return 0;
}
int main() {
char *buff = NULL;
itoa(45, buff);
printf("%s\n", buff);
}
Your pointer isn't modified as it was copied. You can read more here. You can try this code after reading the above link.
#include <stdlib.h>
#include <stdio.h>
int itoa_(int i, char **parabuff)
{
int length = 0;
// get the length
long temp = 1;
while (temp <= i)
{
length++;
temp *= 10;
}
char *buff = malloc(length + 1); // buff will have 'length' chars + one extra (\0)
int j = 0;
do
{ /* generate digits in reverse order */
buff[j++] = i % 10 + '0'; /* get next digit */
} while ((i /= 10) > 0); /* delete it */
buff[length] = '\0';
// reverse it
int k, l;
char c;
for (k = 0, l = length - 1; k < l; k++, l--)
{
c = buff[k];
buff[k] = buff[l];
buff[l] = c;
}
printf("buff's now: %s\n", buff);
*parabuff = buff;
return 0;
}
int main()
{
char *buff = NULL;
itoa_(45, &buff);
printf("buff in main: %s\n", buff);
}
//OUTPUT
buff's now: 45
buff in main: 45

What am I doing wrong with malloc and realloc of array of struct?

I'm trying to build in C an array of structures without defining the length of the maximum size of the array.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct text {
char *final;
} text;
int main() {
int n, sizearray = 10, i;
char *str;
text *testo;
testo = (text *)malloc(sizeof(text) * sizearray);
fgets(str, 1024, stdin);
i = 0;
while (str[0] != 'q') {
if (i == sizearray - 1) {
testo = (text *)realloc(testo, sizearray * 2 * sizeof(text));
}
n = strlen(str);
n = n + 1;
testo[i].finale = (char *)malloc(sizeof(char) * n);
strcpy(testo[i].finale, str);
i++;
fgets(str, 1024, stdin);
}
for (i = 0; i < sizearray; i++)
printf("%s \n", testo[i].finale);
return 0;
}
this gives me
process finished with exit code 139 (interrupted by signal 11:SIGSEV).
What am I doing wrong?
There are multiple issues in your code:
[major] str is an uninitialized pointer. You should make it an array of char defined with char str[1024].
[major] you do not adjust sizearray when you double the size of the array, hence you will never reallocate the array after the initial attempt at i = 9.
[major] the final loop goes to sizearray but there are potentially many uninitialized entries at the end of the array. You should stop at the last entry stored into the array.
you should also check the return value of fgets() to avoid an infinite loop upon premature end of file.
you should test for potential memory allocation failures to avoid undefined behavior.
Here is a modified version:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct text {
char *finale;
} text;
int main() {
char str[1024];
text *testo = NULL;
size_t sizearray = 0;
size_t i, n = 0;
while (fgets(str, sizeof str, stdin) && *str != 'q') {
if (n == sizearray) {
/* increase the size of the array by the golden ratio */
sizearray += sizearray / 2 + sizearray / 8 + 10;
testo = realloc(testo, sizearray * sizeof(text));
if (testo == NULL) {
fprintf(stderr, "out of memory\n");
return 1;
}
}
testo[n].finale = strdup(str);
if (testo[n].finale == NULL) {
fprintf(stderr, "out of memory\n");
return 1;
}
n++;
}
for (i = 0; i < n; i++) {
printf("%s", testo[i].finale);
}
for (i = 0; i < n; i++) {
free(testo[i].finale);
}
free(testo);
return 0;
}
str is uninitialized. Either allocate memory with malloc or define it as an array with char str[1024].

memory allocation problem while reading a file

I'm trying to multiply two matrices stored in a file thus formatted:
1 2
2 3
*
-4 1
1 0
I do not know initially what the dimension of each matrix is. But I let the user define it or otherwise a default value of 100 is taken.
int maxc = argc > 2 ? atoi(argv[2]) * atoi(argv[2]) : 100;
I can already perform the calculation correctly, but I've noticed that if I enter the dimension argv[2] = "2" so that maxc = 8, (that should be enough for this example), errors are produced in reading or printing the file. But if I enter argv[2] = "3" everything works out fine for this example. Since maxc is used to allocate memory here: matrix = malloc(maxc * sizeof *matrix), I suspect the problem could be located on that line. Should I allocate memory also for size_t row; size_t col;?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define MAXNOP 50 /*Max number of operations allowed */
#define MAXNMATR 20 /*Max number of matrices */
struct m {
size_t row;
size_t col;
double *data;
};
struct m multiply(struct m *A, struct m *B);
void f(double x);
void print_matrix(struct m *A);
void read_file(int maxc, FILE *fp);
void scalar_product(double scalar, struct m *B);
void calculate(struct m *matrix, int nop, int id, char *op);
int main(int argc, char *argv[]) {
FILE *file = argc > 1 ? fopen(argv[1], "rb") : stdin;
/* define max dimension of a matrix */
int maxc = argc > 2 ? atoi(argv[2]) * atoi(argv[2]) : 100;
read_file(maxc, file);
return 0;
}
void read_file(int maxc, FILE *fp) {
struct m *matrix;
int id = 0; /* id of a matrix */
size_t ncol, nrow; /* No of columns of a matrix*/
ncol = nrow = 0;
int nop = 0; /*No of operators*/
int off = 0;
int i;
int n;
double *d;
char buf[2 * maxc]; /*to store each lines of file */
char *p = buf;
char op[MAXNOP];
for (i = 0; i < MAXNOP; i++)
op[i] = '?';
if (!(matrix = malloc(maxc * sizeof *matrix))) {
perror("malloc-matrix");
exit(1);
}
/* Read file line by line */
while (fgets(buf, maxc, fp)) {
if (nrow == 0) {
/* allocate/validate max no. of matrix */
d = matrix[id].data = malloc(sizeof(double) * MAXNMATR);
}
/* check if line contains operator */
if ((!isdigit(*buf) && buf[1] =='\n')) {
op[nop++] = *buf;
matrix[id].col = ncol;
matrix[id].row = nrow;
nrow = ncol = 0;
id++;
continue;
} else {
/* read integers in a line into d */
while (sscanf(p + off, "%lf%n", d, &n) == 1) {
d++;
if (nrow == 0)
ncol++;
off += n;
}
nrow++;
off = 0;
}
} /*end of while fgets cycle */
/* Assign last matrix No of columns and rows */
matrix[id].col = ncol;
matrix[id].row = nrow;
/* Printing the matrices and operations */
for (i = 0; i <= id; i++) {
if (op[i] == '*' || op[i] == '-' || op[i] =='+') {
print_matrix(&matrix[i]);
if (op[i-1] != 'i')
printf("%c\n", op[i]);
else
continue;
} else
if (op[i] == '?') {
print_matrix(&matrix[i]);
}
}
calculate(matrix, nop, id, op);
}
void calculate(struct m *matrix, int nop, int id, char *op) {
int i;
for (i = 0; i <= nop; i += 2) {
if (op[i] == '*' && op[i+1] == '?') {
if (matrix[i].row == 1 && matrix[i].col == 1)
scalar_product(matrix[i].data[0], &matrix[i + 1]); //Multiplication of Scalar per matrix
else {
matrix[i + 1] = multiply(&matrix[i], &matrix[i + 1]);
matrix[i + 2] = multiply(&matrix[i + 1], &matrix[i + 2]);
}
break;
}
}
printf("=\n");
print_matrix(&matrix[id]); /* Print the result */
free(matrix);
}
struct m multiply(struct m *A, struct m *B) {
size_t i, j, k;
struct m C;
C.data = malloc(sizeof(double) * A->row * B->col);
C.row = A->row;
C.col = B->col;
for (i = 0; i < C.row; i++)
for (j= 0 ; j < C.col; j++)
C.data[i * C.col + j] = 0;
// Multiplying matrix A and B and storing in C.
for (i = 0; i < A->row; ++i)
for (j = 0; j < B->col; ++j)
for (k = 0; k < A->col; ++k)
C.data[i * C.col + j] += A->data[i * A->col + k] * B->data[k * B->col + j];
return C;
}
void f(double x) {
double i, f = modf(x, &i);
if (f < .00001)
printf("%.f ", i);
else
printf("%f ", x);
}
/* printing a Matrix */
void print_matrix(struct m *A) {
size_t i, j;
double *tmp = A->data;
for (i = 0; i < A->row; i++) {
for (j = 0; j < A->col; j++) {
f(*(tmp++));
}
putchar('\n');
}
}
void scalar_product(double scalar, struct m *B) {
size_t i, j;
for (i = 0; i < B->row; i++)
for (j = 0; j < B->col; j++)
B->data[i * B->col + j] = scalar * B->data[i * B->col + j];
}
The expected result is this: https://ideone.com/Z7UtiR
here argv[2] is not read so there is enough memory to store all data.
Your read buffer only has room for maxc (ie. 4) characters :
char buf[maxc]; /*to store each lines of file */
You then attempt to get a line from the file into that buffer :
while (fgets (buf, maxc, fp)){
But that buffer is only large enough for 2 characters, followed by a newline, and then a '\0' terminator.
Looking at your sample file, the longest line has 4 characters : "-4 1". So, your buffer needs to at least be able to hold 6 (including the newline and '\0' terminator).
It's probably better to make your buffer quite a bit larger.
The problem is entirely in reading the arrays.
The maxc = 4 and the buffer char buf[maxc]; has place only for 3 characters and terminating character.
So fgets (buf, maxc, fp):
on the first will read buf = "1 2" (3 characters and zero byte)
on the second will read buf = "\n" (1 newline character, fgets terminates)
then reads buf = "2 3"
then reads buf = "\n"
buf = "*\n"
buf = "-4 "
and so on
Because of the empty line, inside this code snipped:
else /* read integers in a line into d */
{
while (sscanf (p + off, "%lf%n", d, &n) == 1) {
d++;
if(nrow == 0)
ncol++;
off += n;
}
nrow++;
off = 0;
}
The variable nrow will be incremented 4 times (2 times for rows, and 2 times for empty lines with only newlines read), which will be 2 times too many. The second matrix will have 1 column, because you will read only -4 from the line, so your while(sscanf loop will scan only one number, so ncol will be only 1.
Your fix you posted in the comment is invalid, because you only increased buffer size, but didn't increase the size argument you pass to fgets. If you did char buf[2*maxc]; you also should fgets (buf, 2 * maxc, fp), which will "fix" the current problem. I would rather re-write the whole thing or rather write fgets(buf, sizeof(buf)/sizeof(buf[0]), fp) to accommodate future changes.
Don't use VLAs ex. char buf[maxc];. For simplicity you can use arbitrary long buffer for the line, ex. #define LINE_MAX 1024 and char buf[LINE_MAX] and then fgets(buf, sizeof(buf)/sizeof(buf[0]), file). Or use or rewrite function that will dynamically resize memory and read line, like GNUs getline.

How to go through a array of strings using pointers alone

I'm trying to create a function that will receive an array of strings and the size and will return a string made of the biggest ASCII value's letter of each word, and the size of the string has to be precised and I'm not allowed using operator [](which is my main issue).
so for:
char *strArr[SIZE] = { "hello", "and", "good", "morning" };
the function shall return a string with the word
"onor"
.
So i thought of creating a double for loop, first one will lead me into the location of each word in the array and the inside one will help me go through each word.
currently I'm having trouble finding the right format with my pointers to actually go through the letters of my first word.
I'm aware i haven't checked if my memory allocation is valid and also didn't free my memory yet as I'm trying to figure out whats wrong first.
char *bigLetters(char *str[], int size)
{
char *strNew = (char *)malloc((size + 1) * sizeof(char));
char max = 'a';
for (int i = 0; i < size; i++)
{
for (int j = 0; (*(str + i)+j) != NULL; j++)
{
if ((*(str + i) + j) >= max)
{
max = (*(str + i) + j);
}
}
*(strNew + i) = max;
}
*(strNew +(size+1)) = NULL;
return *(strNew);
}
void main()
{
char *strArr[SIZE] = { "hello", "and", "good", "morning" };
char *res = bigLetters(strArr, SIZE);
printf("The new string is --> %s\n", res);
system("pause");
}
It will be easier to use the pointers if you separate the string pointer from its character pointer. Also, the max needs to be reset for each string, and you were writing the final string terminator outside of the memory allocated. You also use NULL where you should be using the character '\0'.
Finally the function was returning the first character of the new string (which I later free).
#include <stdio.h>
#include <stdlib.h>
#define SIZE 4
char *bigLetters(char *str[], int size)
{
char *strNew = malloc(size + 1); // no cast or sizeof necessary
for (int i = 0; i < size; i++)
{
char ch;
char max = 'a'; // moved inside loop
char *ptr = *(str + i); // use a separate pointer
for (int j = 0; (ch = *(ptr + j)) != '\0'; j++) // pull out the character
{
if (ch > max) // >= is not necessary
{
max = ch;
}
}
*(strNew + i) = max;
}
*(strNew + size) = '\0'; // correct the bounds error
return strNew; // just the pointer not its target
}
int main(void) // correct signature
{
char *strArr[SIZE] = { "hello", "and", "good", "morning" };
char *res = bigLetters(strArr, SIZE);
printf("The new string is --> %s\n", res);
free(res); // clean up
system("pause");
}
Program output
The new string is --> onor
Press any key to continue . . .
If you didn't impose odd and unhelpful restrictions upon your coding, you'd be able to quickly see the problems with your code or even avoid making them in the first place. The problem is that the following statement makes no sense - you're comparing a char * with a char as you're only de-referencing str once.
if ((*(str + i) + j) >= max)
This is the same as writing
if ((str[i] + j) >= max)
which you can see the obvious mistake since what you're trying to write is the equivalent of
if ((str[i][j]) >= max)
which would be
if (*(*(str + i) + j) >= max)
Your compiler should be throwing up warnings because comparing between a pointer and an integer is rarely something you'd want to do.
You can use pointers as position indicators and advance them as needed.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 4
char
biggest_ascii(char* str)
{
char c = 0;
int i;
for (i = 0; *str; str++)
if (*str > c)
c = *str;
return c;
}
int
main()
{
int i;
char* strArr[SIZE] = {"hello", "and", "good", "morning"};
char** ppch;// current string
char res_str[SIZE + 1] = {0};/* resulting string,
initilized to 0 to be 0-terminated */
char* pch;// current char position
for (i = 0, ppch = strArr, pch = res_str; i < SIZE; i++, ppch++, pch++)
*pch = biggest_ascii(*ppch);
printf("%s\n", res_str);
return 0;
}
First, (*(str + i)+j) isn't the good way.
You could replace all
(*(str + i) + j)
by :
str[i][j]
Then, you need to reset the max to "a", because it's 'o' when you leave the loop, so your condition become str[i][j] >= o which is not what you want. Do it before the second for.
And I would have used while instead of for for the first loop.
I edited your code and this version is working fine for me :
#include <stdlib.h>
char *bigLetters(char *str[], int size)
{
char *strNew = (char *)malloc((size + 1) * sizeof(char));
int i = 0;
while (i < size) {
char max = 'a';
for (int j = 0; str[i][j]; j++) {
if (str[i][j] >= max) {
max = str[i][j];
}
}
strNew[i] = max;
i++;
}
strNew[i] = '\0';
return strNew;
}
void main()
{
char *strArr[5] = { "hello", "and", "good", "morning"};
char *res = bigLetters(strArr, 4);
printf("The new string is --> %s\n", res);
return 0;
}
str[i] is equivalent to *(str + i) and str[i][j] is equivalent to *(*(str + i) + j).
In your code you are using (*(str + i) + j) which is incorrect.
When char *[] passed to function, it will decay to char **. So, in bigLetters(), you can give char **str as the parameter. Also, it is inline with you requirement - not allowed using operator [].
Instead of hardcoding the dimension SIZE in char *strArr[SIZE], you can give the empty [] and let the compiler assign the dimension based on the size of initializer. In your case, size of initializer is 4 as you have given 4 strings in the strArr initializer. You can compute the size of strArr like this:
sizeof(strArr)/sizeof(strArr[0]);
You can do:
#include <stdio.h>
#include <stdlib.h>
char *bigLetters(char **str, size_t size) {
char *strNew = calloc(size + 1, 1); // sizeof(char) is always 1
// calloc will initialize all bytes in the allocated storage to zero.
// You dont need to add the null terminating character at the end of strNew
if (strNew == NULL)
exit(EXIT_FAILURE);
for (size_t i = 0; i < size; i++) {
for (size_t j = 0; *(*(str + i)+j) != '\0'; j++) {
if (*(*(str + i) + j) > *(strNew + i)) {
// You can directly fill the allocated memory with biggest ASCII
*(strNew + i) = *(*(str + i) + j);
}
}
}
return strNew;
}
int main(void) {
char *strArr[] = { "hello", "and", "good", "morning" };
char *res = bigLetters(strArr, sizeof(strArr)/sizeof(strArr[0]));
if (res != NULL) {
printf("The new string is --> %s\n", res);
free (res);
}
else
printf("bigLetters returned NULL\n");
return 0;
}
Note that void return type main() is not as per standard. Instead, you should use int as return type of main().

How to print a numerical matrix into a string in C?

Suppose we have a matrix in C (a 2D array).
I wonder how could I print the matrix into a string in C.
For example, if I have
double M[2][2]={{1.2,3.4},{3.14,2.718}}
I want to get a string like this:
"1.200 3.400\n3.140 2.718"
which could be printed as
1.200 3.400
3.140 2.718
If print to screen, the problem will become easier because we need not consider the buffer size. However, when printing to a string, it seems hard to know how large the string buffer should be, if I want to use functions like 'sprintf'.
I searched google and stackoverflow but almost all of what I get is about how to convert string to numerical...
How to do this in C? Are there any libs?
Could you please help? Thank you!
EDIT:
The 'snprintf' solution works well for the situation of just one number.
But for matrix, it is supposed to use loops to go through every element.
And then add a little to the string in each loop. Will this work with 'snprintf'?
You'll need to do this in two steps, first calculate the total size to hold the string, then allocate it and compose the string. Could be done in a function like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
static char * matrix2D_to_string(const double *matrix, size_t rows, size_t columns)
{
const char format[] = "%f";
const char column_separator[] = " ";
const char row_separator[] = "\n";
int *column_widths = NULL;
size_t r = 0, c = 0;
char *buffer = NULL, *p = NULL;
size_t size = 0;
if (!rows || ! columns) {
errno = EINVAL;
return NULL;
}
// calculate maximum width for each column
column_widths = (int *)calloc(columns, sizeof(*column_widths));
for (r = 0; r < rows; ++r) {
for (c = 0; c < columns; ++c) {
char buf[256];
int width = sprintf(buf, format, matrix[r * columns + c]);
if (width > column_widths[c]) {
column_widths[c] = width;
}
}
}
// calculate total buffer size...
// ... values
for (c = 0; c < columns; ++c) {
size += column_widths[c] * rows;
}
// ... column separators
size += (columns - 1) * strlen(column_separator);
// ... row separators
size += (rows - 1) * strlen(row_separator);
// ... nul terminator
++size;
// make the string
buffer = (char *)malloc(size);
p = buffer;
for (r = 0; r < rows; ++r) {
if (r) {
strcpy(p, row_separator);
p += strlen(row_separator);
}
for (c = 0; c < columns; ++c) {
if (c) {
strcpy(p, column_separator);
p += strlen(column_separator);
}
int width = sprintf(p, format, matrix[r * columns + c]);
p += width;
if (width < column_widths[c]) {
width = column_widths[c] - width;
memset(p, ' ', width);
p += width;
}
}
}
*p = '\0';
// cleanup
free(column_widths);
return buffer;
}
int main()
{
double M[3][2]={{1.2,3.4},{3.14,2.718},{100.999,0.000005}};
char *s = matrix2D_to_string((const double *)M, ARRAY_SIZE(M), ARRAY_SIZE(M[0]));
puts(s);
free(s);
return 0;
}
This prints:
1.200000 3.400000
3.140000 2.718000
100.999000 0.000005
You may use snprintf to get buffer length you need first and then allocate and print into it:
char* PrettyPrint(const char* format, ...)
{
va_args va;
va_start(va, format);
char c[1] = {};
int len = vsnprintf(c, 1, format, va);
char* s = malloc(len + 1);
vsnprintf(s, len + 1, format, va);
va_end(va);
return s;
}
You can start with some estimated size, and use realloc if it isn't enough.
If snprintf returns more than the remaining buffer size, it means it didn't have enough room. In this case, you should reallocate, and retry the same snprintf.
Its array.
considering float values.
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
printf("%f \t",M[i][j]);
}
printf("\n");
}
Hope this will help you.
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
printf("%f \t",M[i][j]);
}
printf("\\n");//Change printf("\n") as printf("\\n")
}
#include <stdio.h>
#include <stdlib.h>
long GetFileSize(FILE *fp){
long fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);//reset stream position!!
return fsize;
}
char *ReadToEnd(const char *filepath){
FILE *fp;
long fsize;
char *buff;
if(NULL==(fp=fopen(filepath, "rb"))){
perror("file cannot open at ReadToEnd\n");
return NULL;
}
fsize=GetFileSize(fp);
buff=(char*)malloc(sizeof(char)*fsize+1);
fread(buff, sizeof(char), fsize, fp);
fclose(fp);
buff[fsize]='\0';
return buff;
}
char *printStrMatrix(const char *fmt, const int col, const int row, const double* matrix ){
FILE *fp;
int c,r;
char *str;
if(NULL==(fp=fopen("printStr.tmp", "wb"))){//use tmpnam() better
perror("temporary file cannot open at printStr\n");
return NULL;
}
for(r=0;r<row;++r){
for(c=0;c<col;++c){
fprintf(fp, fmt, *matrix++);
if(c != col-1)
fprintf(fp, " ");
}
fprintf(fp, "\n");
}
fflush(fp);
fclose(fp);
str=ReadToEnd("printStr.tmp");
remove("printStr.tmp");
return str;
}
int main(void){
double M[2][2]={{1.2,3.4},{3.14,2.718}};
char *str;
str=printStrMatrix("%1.3lf", 2, 2, &M[0][0]);
printf("%s", str);
free(str);
return 0;
}

Resources