lo ideal es que tus funciones que realicen un proceso X retornen códigos de error para que funciones madres por ejemplo main sepa que hacer ante mas de 1 o 2 situaciones. se puede usar de una manera pero seria con fprintf() en conjunto a Standard error stream (stderr) solamente para debugear y mostrar los errores, pero que solo una persona especializada (en este caso tu) sepas que a ocurrido y el usuario normal solo se preocupe en su funcionamiento y no en codigo o errores que a final de cuentas a el no le interesan... un ejemplo:
Código
#include <stdlib.h>
#include <stdio.h> //<stdio.h>
#include <string.h>
char* readInput(FILE* FileSrc)
// Retorna un puntero a una cadena ansi que debera ser liberada con free();
{
char c = 0;
char *szRet = NULL;
size_t size = 0;
while(++size)
{
szRet = (char*)realloc(szRet, size);
fread(&c, 1, 1, FileSrc);
if (c == '\n')
break; // exit while(1)
szRet[size - 1] = c;
}
return szRet;
}
long int getActionFromString(const char *szStr)
// Verifica la existencia de vocales dentro de una cadena dada.
{
long int lFlags = 0;
if (szStr)
{
do
{
switch(*szStr) // <-- en luigar de poner los printf usamos flags para saber que hacer en un proceso que nos llamo...
{
case 'A':case 'a': lFlags |= 0x1;
break;
case 'E':case 'e': lFlags |= 0x2;
break;
case 'I':case 'i': lFlags |= 0x4;
break;
case 'O':case 'o': lFlags |= 0x8;
break;
case 'U':case 'u': lFlags |= 0x10;
break;
}
} while (*(++szStr) != '\0');
}
return lFlags;
}
int main()
{
// claro evita poner mucho codigo tambien en el main()... evita esto que hice.
char* szTmp = NULL;
long int lFlags = 0;
puts("ingresa una cadena:");
szTmp = readInput(stdin);
lFlags = getActionFromString(szTmp);
if (lFlags == 0x0)
{
fprintf(stdout, "Cadena limpia de vocales\n");
} else {
fprintf(stdout, "Error cadena con vocales\n");
if (lFlags & 0x1)
fprintf(stderr, "Error Contiene la vocal \"a\" code: %d\n", lFlags);
if (lFlags & 0x2)
fprintf(stderr, "Error Contiene la vocal \"e\" code: %d\n", lFlags);
if (lFlags & 0x4)
fprintf(stderr, "Error Contiene la vocal \"i\" code: %d\n", lFlags);
if (lFlags & 0x8)
fprintf(stderr, "Error Contiene la vocal \"o\" code: %d\n", lFlags);
if (lFlags & 0x10)
fprintf(stderr, "Error Contiene la vocal \"u\" code: %d\n", lFlags);
}
free(szTmp);
return EXIT_SUCCESS;
}
Dulces Lunas!¡.
La verdad que me mareé con esta respuesta. En mi humilde opinión te puedo decir que la razón por la que los libros dicen que es incorrecto usar printf y scanf en funciones, se debe
a puros formalismos.
(Corrección: Se debe en parte a la formalidad en el uso de una función)Porque, si se trata de una función que devuelve un único valor ya sea
int,
char,
bool, o algún otro tipo que no sea
void, lo correcto sería que a esta función se le proporcione toda la información de entrada mediante sus parámetros. Osea, en la llamada a la función, la unidad (programa principal o algún subprograma) que llama a la función debe pasarle toda la información necesaria mediante la lista de argumentos (y así se evita pedir más información mediante
scanf) para que trabaje con ellos y luego, una vez procesados, devuelva algún resultado mediante la setencia
return (y ya no con la función
printf). Ya que este debería ser el uso que se le debería dar a una función de manera legal, formal y correcta.
Cuando se trata de funciones que devuelve el tipo
void ya es muy diferente, porque en realidad, estas ya no son funciones propiamente dichas sino que se tratarían de
procedimientos. Generalmente en los procedimientos (funciones que retornan el tipo void) se vería no tan mal el uso de printf y scanf. Esa es mi opinión.