C print a generic type vector
up vote
2
down vote
favorite
Hi I'm trying to create a function that takes a void* pointer as parameter and print all element of the vector using printf
the declaration of the function is:
void print_vec(void *vec,int dime_se,int dime,char *format);
and implementation is:
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
printf(format,*(vec+dime_se*i));
the problem is that when i compile the compiler returns:
error: invalid use of void expression printf(format,*(vec+dime_se*i));
So the question there is a way to do this task without make this?
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
switch(format[1])
case 'c':
printf(format,*((char*)(vec+dime_se*i)));
break;
case 'd':
printf(format,*((unsigned int*)(vec+dime_se*i)));
break;
case 's':
printf(format,*((char**)(vec+dime_se*i)));
break;
case 'i':
printf(format,*((int*)(vec+dime_se*i)));
break;
case 'f':
printf(format,*((float*)(vec+dime_se*i)));
break;
default:
break;
c vector printf
add a comment |
up vote
2
down vote
favorite
Hi I'm trying to create a function that takes a void* pointer as parameter and print all element of the vector using printf
the declaration of the function is:
void print_vec(void *vec,int dime_se,int dime,char *format);
and implementation is:
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
printf(format,*(vec+dime_se*i));
the problem is that when i compile the compiler returns:
error: invalid use of void expression printf(format,*(vec+dime_se*i));
So the question there is a way to do this task without make this?
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
switch(format[1])
case 'c':
printf(format,*((char*)(vec+dime_se*i)));
break;
case 'd':
printf(format,*((unsigned int*)(vec+dime_se*i)));
break;
case 's':
printf(format,*((char**)(vec+dime_se*i)));
break;
case 'i':
printf(format,*((int*)(vec+dime_se*i)));
break;
case 'f':
printf(format,*((float*)(vec+dime_se*i)));
break;
default:
break;
c vector printf
1
no. C have not generic types. to callprintfwith valid arguments compiler need extra information about size of arguments. in your example you useint,char,floatandchar*and they can have any size depends on your machine
– kerrytazi
2 days ago
1
Pointer math onvoid*is not portable.(unsigned int*)(vec+dime_se*i)-->((unsigned int*)vec + i)
– chux
2 days ago
1
Why use'd'withunsigned?'d'goes withint.'u'goes withunsigned.
– chux
2 days ago
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Hi I'm trying to create a function that takes a void* pointer as parameter and print all element of the vector using printf
the declaration of the function is:
void print_vec(void *vec,int dime_se,int dime,char *format);
and implementation is:
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
printf(format,*(vec+dime_se*i));
the problem is that when i compile the compiler returns:
error: invalid use of void expression printf(format,*(vec+dime_se*i));
So the question there is a way to do this task without make this?
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
switch(format[1])
case 'c':
printf(format,*((char*)(vec+dime_se*i)));
break;
case 'd':
printf(format,*((unsigned int*)(vec+dime_se*i)));
break;
case 's':
printf(format,*((char**)(vec+dime_se*i)));
break;
case 'i':
printf(format,*((int*)(vec+dime_se*i)));
break;
case 'f':
printf(format,*((float*)(vec+dime_se*i)));
break;
default:
break;
c vector printf
Hi I'm trying to create a function that takes a void* pointer as parameter and print all element of the vector using printf
the declaration of the function is:
void print_vec(void *vec,int dime_se,int dime,char *format);
and implementation is:
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
printf(format,*(vec+dime_se*i));
the problem is that when i compile the compiler returns:
error: invalid use of void expression printf(format,*(vec+dime_se*i));
So the question there is a way to do this task without make this?
void print_vec(void *vec,int dime_se,int dime,char *format)
for(int i=0;i<dime;i++)
switch(format[1])
case 'c':
printf(format,*((char*)(vec+dime_se*i)));
break;
case 'd':
printf(format,*((unsigned int*)(vec+dime_se*i)));
break;
case 's':
printf(format,*((char**)(vec+dime_se*i)));
break;
case 'i':
printf(format,*((int*)(vec+dime_se*i)));
break;
case 'f':
printf(format,*((float*)(vec+dime_se*i)));
break;
default:
break;
c vector printf
c vector printf
asked 2 days ago
P.Carlino
394114
394114
1
no. C have not generic types. to callprintfwith valid arguments compiler need extra information about size of arguments. in your example you useint,char,floatandchar*and they can have any size depends on your machine
– kerrytazi
2 days ago
1
Pointer math onvoid*is not portable.(unsigned int*)(vec+dime_se*i)-->((unsigned int*)vec + i)
– chux
2 days ago
1
Why use'd'withunsigned?'d'goes withint.'u'goes withunsigned.
– chux
2 days ago
add a comment |
1
no. C have not generic types. to callprintfwith valid arguments compiler need extra information about size of arguments. in your example you useint,char,floatandchar*and they can have any size depends on your machine
– kerrytazi
2 days ago
1
Pointer math onvoid*is not portable.(unsigned int*)(vec+dime_se*i)-->((unsigned int*)vec + i)
– chux
2 days ago
1
Why use'd'withunsigned?'d'goes withint.'u'goes withunsigned.
– chux
2 days ago
1
1
no. C have not generic types. to call
printfwith valid arguments compiler need extra information about size of arguments. in your example you use int, char, float and char* and they can have any size depends on your machine– kerrytazi
2 days ago
no. C have not generic types. to call
printfwith valid arguments compiler need extra information about size of arguments. in your example you use int, char, float and char* and they can have any size depends on your machine– kerrytazi
2 days ago
1
1
Pointer math on
void* is not portable. (unsigned int*)(vec+dime_se*i) --> ((unsigned int*)vec + i)– chux
2 days ago
Pointer math on
void* is not portable. (unsigned int*)(vec+dime_se*i) --> ((unsigned int*)vec + i)– chux
2 days ago
1
1
Why use
'd' with unsigned? 'd' goes with int. 'u' goes with unsigned.– chux
2 days ago
Why use
'd' with unsigned? 'd' goes with int. 'u' goes with unsigned.– chux
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
You don't need the dime_se param. The size is more or less implicit in the format character.
Also, if you cast to the right pointer type you can let C do the scaling instead of doing it
manually:
#include <stddef.h>
#include <stdio.h>
void print_vec(void const*vec,size_t dime,char const*format)
for(size_t i=0;i<dime;i++)
switch(format[1])
#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])
X('c',char);
X('d',unsigned);
X('s',char*);
X('i',int);
X('f',float);
break;default: return;
#undef X
I said more or less because type promotion kind of blurs the line. %f could well mean you've got a double instead of a float.
If you want to use a dime_se parameter to disambiguate that case, you can:
break;case 'f':
if(sizeof(double)==dime_se)
printf(format,((double*)vec)[i]);
else
assert(sizeof(float)==dime_se);
printf(format,((float*)vec)[i]);
but I'm not sure if a print_vec function like that is a good idea.
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any'f'returns right after printing (drop through) . Curious: why#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])and not#define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break?
– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see eachcasepreceded bybreak;it'll make one that isn't stand out more easily than if thebreakwere at the end of what follows thecase. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the firstcasewithbreakeven though thebreakpart is basically dead code there.
– PSkocik
2 days ago
Hmmm, If you valuebreakat the beginning, perhaps then#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); breakto avoid the earlier coding oops that caused a "accidental fall-through".
– chux
2 days ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
You don't need the dime_se param. The size is more or less implicit in the format character.
Also, if you cast to the right pointer type you can let C do the scaling instead of doing it
manually:
#include <stddef.h>
#include <stdio.h>
void print_vec(void const*vec,size_t dime,char const*format)
for(size_t i=0;i<dime;i++)
switch(format[1])
#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])
X('c',char);
X('d',unsigned);
X('s',char*);
X('i',int);
X('f',float);
break;default: return;
#undef X
I said more or less because type promotion kind of blurs the line. %f could well mean you've got a double instead of a float.
If you want to use a dime_se parameter to disambiguate that case, you can:
break;case 'f':
if(sizeof(double)==dime_se)
printf(format,((double*)vec)[i]);
else
assert(sizeof(float)==dime_se);
printf(format,((float*)vec)[i]);
but I'm not sure if a print_vec function like that is a good idea.
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any'f'returns right after printing (drop through) . Curious: why#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])and not#define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break?
– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see eachcasepreceded bybreak;it'll make one that isn't stand out more easily than if thebreakwere at the end of what follows thecase. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the firstcasewithbreakeven though thebreakpart is basically dead code there.
– PSkocik
2 days ago
Hmmm, If you valuebreakat the beginning, perhaps then#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); breakto avoid the earlier coding oops that caused a "accidental fall-through".
– chux
2 days ago
add a comment |
up vote
4
down vote
accepted
You don't need the dime_se param. The size is more or less implicit in the format character.
Also, if you cast to the right pointer type you can let C do the scaling instead of doing it
manually:
#include <stddef.h>
#include <stdio.h>
void print_vec(void const*vec,size_t dime,char const*format)
for(size_t i=0;i<dime;i++)
switch(format[1])
#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])
X('c',char);
X('d',unsigned);
X('s',char*);
X('i',int);
X('f',float);
break;default: return;
#undef X
I said more or less because type promotion kind of blurs the line. %f could well mean you've got a double instead of a float.
If you want to use a dime_se parameter to disambiguate that case, you can:
break;case 'f':
if(sizeof(double)==dime_se)
printf(format,((double*)vec)[i]);
else
assert(sizeof(float)==dime_se);
printf(format,((float*)vec)[i]);
but I'm not sure if a print_vec function like that is a good idea.
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any'f'returns right after printing (drop through) . Curious: why#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])and not#define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break?
– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see eachcasepreceded bybreak;it'll make one that isn't stand out more easily than if thebreakwere at the end of what follows thecase. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the firstcasewithbreakeven though thebreakpart is basically dead code there.
– PSkocik
2 days ago
Hmmm, If you valuebreakat the beginning, perhaps then#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); breakto avoid the earlier coding oops that caused a "accidental fall-through".
– chux
2 days ago
add a comment |
up vote
4
down vote
accepted
up vote
4
down vote
accepted
You don't need the dime_se param. The size is more or less implicit in the format character.
Also, if you cast to the right pointer type you can let C do the scaling instead of doing it
manually:
#include <stddef.h>
#include <stdio.h>
void print_vec(void const*vec,size_t dime,char const*format)
for(size_t i=0;i<dime;i++)
switch(format[1])
#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])
X('c',char);
X('d',unsigned);
X('s',char*);
X('i',int);
X('f',float);
break;default: return;
#undef X
I said more or less because type promotion kind of blurs the line. %f could well mean you've got a double instead of a float.
If you want to use a dime_se parameter to disambiguate that case, you can:
break;case 'f':
if(sizeof(double)==dime_se)
printf(format,((double*)vec)[i]);
else
assert(sizeof(float)==dime_se);
printf(format,((float*)vec)[i]);
but I'm not sure if a print_vec function like that is a good idea.
You don't need the dime_se param. The size is more or less implicit in the format character.
Also, if you cast to the right pointer type you can let C do the scaling instead of doing it
manually:
#include <stddef.h>
#include <stdio.h>
void print_vec(void const*vec,size_t dime,char const*format)
for(size_t i=0;i<dime;i++)
switch(format[1])
#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])
X('c',char);
X('d',unsigned);
X('s',char*);
X('i',int);
X('f',float);
break;default: return;
#undef X
I said more or less because type promotion kind of blurs the line. %f could well mean you've got a double instead of a float.
If you want to use a dime_se parameter to disambiguate that case, you can:
break;case 'f':
if(sizeof(double)==dime_se)
printf(format,((double*)vec)[i]);
else
assert(sizeof(float)==dime_se);
printf(format,((float*)vec)[i]);
but I'm not sure if a print_vec function like that is a good idea.
edited 2 days ago
answered 2 days ago
PSkocik
30.1k54267
30.1k54267
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any'f'returns right after printing (drop through) . Curious: why#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])and not#define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break?
– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see eachcasepreceded bybreak;it'll make one that isn't stand out more easily than if thebreakwere at the end of what follows thecase. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the firstcasewithbreakeven though thebreakpart is basically dead code there.
– PSkocik
2 days ago
Hmmm, If you valuebreakat the beginning, perhaps then#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); breakto avoid the earlier coding oops that caused a "accidental fall-through".
– chux
2 days ago
add a comment |
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any'f'returns right after printing (drop through) . Curious: why#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i])and not#define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break?
– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see eachcasepreceded bybreak;it'll make one that isn't stand out more easily than if thebreakwere at the end of what follows thecase. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the firstcasewithbreakeven though thebreakpart is basically dead code there.
– PSkocik
2 days ago
Hmmm, If you valuebreakat the beginning, perhaps then#define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); breakto avoid the earlier coding oops that caused a "accidental fall-through".
– chux
2 days ago
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
Note this answer will only work if your format string always start with a simple type like %d. If you want the function to do fancier printing like fixed number of decimals "%.02f", or print an entire message for each item in the vector, you would need a more complex parsing logic to rely on the format string for typing.
– Lev M.
2 days ago
1
1
@chux Missed that. Thanks.
– PSkocik
2 days ago
@chux Missed that. Thanks.
– PSkocik
2 days ago
As coded, printing any
'f' returns right after printing (drop through) . Curious: why #define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]) and not #define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break ?– chux
2 days ago
As coded, printing any
'f' returns right after printing (drop through) . Curious: why #define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]) and not #define X(Char,Tp) case Char: printf(format,((Tp*)vec)[i]); break ?– chux
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see each
case preceded by break; it'll make one that isn't stand out more easily than if the break were at the end of what follows the case. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the first case with break even though the break part is basically dead code there.– PSkocik
2 days ago
@chux It's just how I write my switches if they contain mostly "breaking-cases". It doesn't matter with the macro, but in normal C code, if I see each
case preceded by break; it'll make one that isn't stand out more easily than if the break were at the end of what follows the case. It helps me quickly catch accidental fall-through. I think it's pretty neat that the C grammar allows me to symmetrically start even the first case with break even though the break part is basically dead code there.– PSkocik
2 days ago
Hmmm, If you value
break at the beginning, perhaps then #define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); break to avoid the earlier coding oops that caused a "accidental fall-through".– chux
2 days ago
Hmmm, If you value
break at the beginning, perhaps then #define X(Char,Tp) break;case Char: printf(format,((Tp*)vec)[i]); break to avoid the earlier coding oops that caused a "accidental fall-through".– chux
2 days ago
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237886%2fc-print-a-generic-type-vector%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
no. C have not generic types. to call
printfwith valid arguments compiler need extra information about size of arguments. in your example you useint,char,floatandchar*and they can have any size depends on your machine– kerrytazi
2 days ago
1
Pointer math on
void*is not portable.(unsigned int*)(vec+dime_se*i)-->((unsigned int*)vec + i)– chux
2 days ago
1
Why use
'd'withunsigned?'d'goes withint.'u'goes withunsigned.– chux
2 days ago