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;












share|improve this question

















  • 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







  • 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' with unsigned? 'd' goes with int. 'u' goes with unsigned.
    – chux
    2 days ago














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;












share|improve this question

















  • 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







  • 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' with unsigned? 'd' goes with int. 'u' goes with unsigned.
    – chux
    2 days ago












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;












share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 days ago









P.Carlino

394114




394114







  • 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







  • 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' with unsigned? 'd' goes with int. 'u' goes with unsigned.
    – chux
    2 days ago












  • 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







  • 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' with unsigned? 'd' goes with int. 'u' goes with unsigned.
    – 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












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.






share|improve this answer






















  • 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 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











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',
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%2f53237886%2fc-print-a-generic-type-vector%23new-answer', 'question_page');

);

Post as a guest






























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.






share|improve this answer






















  • 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 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















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.






share|improve this answer






















  • 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 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













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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








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 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

















  • 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 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
















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


















 

draft saved


draft discarded















































 


draft saved


draft discarded














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














































































這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands