Hilo Oficial de C/C++

1, 2, 3, 4, 5, 6
Necesito vuestra ayuda. Estoy haciendo un programita peor estoy atascado en un sitio. Necesito saber cómo buscar por orden alfabético en ficheros.

Saludos y gracias.
Alguien conoce algun algoritmo para copiar lineas de un fichero de forma recursiva?
Se programar en Java y me gustaria aprender C++, sobre todo programacion grafica.
Alguien me podria enumerar los IDE de desarrollo en C++ que existen. Conozco Borland C++ Builder y he escuchado un tal Visual C++ de microsoft pero no conozco ninguno mas.
Tampoco no estaria de mas ,si conoceis, alguna pagina con tutoriales y ejemplos.
Gracias de antemano.
Para Win, sólo conozco el visual C que es el que uso en la facultad y el dev cpp.
Los demás no se si lo tendrán, pero en el visual puedes conseguir el msdn que es una ayuda y va bastante bien para manejarte un poco con el lenguaje

De tutoriales esta web tiene bastantes ejemplos y explicaciones:
http://c.conclase.net/
Este es un ide gratuito de c/c++ en codigo abierto, muy bueno y con un debbuger.

http://www.bloodshed.net/
Encontre un tutorial muy bueno en internet. Estaba dentro de la pagina de Con Clase aunque la parte de GUI de C++ no se encontraba encuadrado dentro del tutorial de C++ sino que lo han colocado en otra seccion. Esta es http://winapi.conclase.com y trata todo lo relacionado con la libreria de graficos aunque solo de Windows.
Para Linux me imagino habra que utilizar otras herramientas y otras librerias segun estes trabajando con gnome o KDE.
A ver si me podeis echar un cable:

- Tengo por un lado la siguiente estructura:

typedef struct
{
char *nombre;
int num;
} sPersonaje;

--------------------------------------------------------------------------

- En la función main tengo lo siguiente:

int i;
sPersonaje * pPersonajes = NULL;
int numPersonajes = 0;

for (i = 0; i<5; i++)
NuevoPersonaje (&pPersonajes, &numPersonajes);

-----------------------------------------------------------------------------

- Y aquí radica mi problema, no sé cómo reservar la memoria NECESARIA para el nombre de cada personaje:

void NuevoPersonaje(sPersonaje** ppPersonajes, int *num)
{
char aux[50];
int lon;

printf("Autor #%d\n\n", *num + 1);
printf("Nombre: ");
gets(aux);

if (*ppPersonajes = (sPersonaje*) realloc (*ppPersonajes, *num + 1 * sizeof(sPersonaje)) == NULL)

{
printf("No hay suficiente memoria");
exit (-1);
}

lon = strlen(aux);


// ******** Y ahora?? *******

*ppPersonajes[num]->nombre = (etc.......)

*num++;

------------------------------------------------------------------------------

*******No estoy nada seguro, alguien puede ayudarme??


Saludos y muchas gracias.


P.D. No es posible modificar nada de lo expuesto ya que esto es un ejercicio.
Hola, estoy hecho un lio con esto de los punteros [mad] y no se como hacer este problema:

1. Escribir la función cuyo prototipo se muestra a continuación:

void scan_linea(char linea[], int* pv, int* pc, int *pd, int* pw, int*po);

que cuente el número de vocales, consonantes, dígitos, caracteres en blanco y otros caracteres de una línea de texto si se tiene la siguiente función main:

#include

main(){
char linea[80]; // linea de texto
int vocales=0; // contador de vocales
int consonantes=0; // contador de consonantes
int digitos=0; // contador de digitos
int blancos=0; // contador de blancos
int otros=0; // contador de otros caracteres

cout << " Introducir una línea de texto: \n";
cin >> linea;

scan_linea(linea, &vocales, &consonantes, &digitos, &blancos, &otros);

cout << "\nNúmero de vocales: " << vocales;
cout << "\nNúmero de consonantes: " << consonantes;
cout << "\nNúmero de dígitos : " << digitos;
cout << "\nNúmero de caracteres en blanco: " << blancos;
cout << "\nNúmero de otros caracteres: " << otros;
}


Alguien sabe como hacerle?
Veamos, la funcion en si es muy sencilla.

Si el lio viene por los punteros intento explicarte:
En esta función 'pv' es la dirección de memoria de 'vocales' y '*pv' es 'vocales'.

Es decir la función no es más que recorrer la cadena de caracteres hasta el final e ir comparando caracter a caracter para saber en que grupo está, y una vez se sabe en que grupo está es incrementar en uno la variable que toca.

Por ejemplo si el caracter es una vocal (*pv)++; ó *pv = *pv + 1 ;

[bye]
Bueno, he escrito este codigo, pero no funciona correctamente cuando le pongo espacios:



#include

void scan_linea(char linea[], int* pv, int* pc, int *pd, int* pw, int* po)
{
for(int i=0;i<=linea[i];i++)
{



switch(tolower(linea[i])) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
(*pv)++;
break;
default:
(*pc)++;


}







while (linea[i]>='0' && linea[i]<='9')
{
(*pd)++;
break;
}
while (linea[i]==' ')
{
(*pw)++;
break;
}
while(!((linea[i]>='0' && linea[i]<='9')||(linea[i]>='A' && linea[i]<='Z')|| (linea[i]>='a' && linea[i]<='z') ||(linea[i]==' ') ||(linea[i]=='\n')))
{
(*po)++;
break;
}





}
}

main()
{
char linea[80]; // linea de texto
int vocales=0; // contador de vocales
int consonantes=0; // contador de consonantes
int digitos=0; // contador de digitos
int blancos=0; // contador de blancos
int otros=0; // contador de otros caracteres

cout << " Introducir una linea de texto: \n";
cin >> linea;

scan_linea(linea, &vocales, &consonantes, &digitos, &blancos, &otros);

cout << "\nNúmero de vocales: " << vocales;
cout << "\nNúmero de consonantes: " << consonantes;
cout << "\nNúmero de dígitos : " << digitos;
cout << "\nNúmero de caracteres en blanco: " << blancos;
cout << "\nNúmero de otros caracteres: " << otros;
}



HELPPPP [triston]
No se si sera eso, pero prueba a hacer las conparaciones del espacio con el numero 32 (int tal cual, sin comillas), no con ' '
JanKusanagi escribió:No se si sera eso, pero prueba a hacer las conparaciones del espacio con el numero 32 (int tal cual, sin comillas), no con ' '


no, sigue igual ¬_¬
Sinless escribió:
no, sigue igual ¬_¬
Ahora que he mirado el codigo completo... usas cin para pillar la string... haz que te imprima la string completa despues de pillarla... cin se corta al primer espacio :P
Sinless escribió: switch(tolower(linea[i])) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
(*pv)++;
break;
default:
(*pc)++;


}

HELPPPP [triston]


Bien, de entrada lo del cin, y de salida que los especiom signos de puntuación y tal te los cuenta como consonantes. creo que la función correcta seria algo así:

void scan_linea(char linea[], int* pv, int* pc, int *pd, int* pw, int* po) {
int i = 0;
while(linea[i] != '\0') {
if( es_vocal (linea[i]) ) *pv++;
else
if( es_consonante (linea[i])) *pc++;
else
if( es_digito( linea[i] )) *pd++;
else
if( es_espacio( linea[i])) *pw++;
else
*po++;
}


Ahora solo te faltaria crear las funciones es_algo que devuelven un bool.

[bye]
Bueno y para la pregunta que hice yo no hay respuesta?
Este jueves me examino ya de la asignatura. ¿Qué me decís?


Saludos.- :-|
Hola a todos!

No tengo ni idea de programación, pero me gustaría empezar a aprender y he elegido C/C++.

Me gustaría saber si hay manuales, ejemplos, o material variado, para poder empezar a intentar comprender y aprender este lenguaje.

Como base tened en cuenta que jamás he programado nada de nada.

Saludos y gracias!!
Wenas, estoy buscando la información basica de como comunicar un programa con c++ con el puerto serie.

Solo me interesa saber que librerias he de cargar, el resto quiero buscarme la vida. El problema es que en internet te dan todo hecho (siempre el mismo ejemplo... valla con la diversificación...) pero me falta justo eso, que librerias son?

Mi idea es basica, cargar una variable boleana, darle un valor y según el valor,que encienda un led por puerto serie.

Además de que los tutos para Windows 98 y compania no chutan, por lo visto el XP trata los puertos de otra forma.
Para usar decimales lo mejor es un double? (usando C)
EnErU, depende del grado de precisión, te puede servir un float o un double.

Ahora necesito yo vuestra ayuda. Es una pregunta muy sencilla:

Estoy creando con C++ un programa que me da funcionalidad total para operar con Polinomios. Tego hechas varias clases, todo bien ordenadito, y he creado una clase CPolinomio que es donde estan todos los monomios.
Dentro de esta clase, tambien tengo un destructor que me libera toda la memoria dinamica.
Ahora estoy sobrecargando el operador de asignacion para que me copie un polinomio en otro, y para ello, el polinimio al que le voy a copiar los datos tiene que estar vacío. Mi pregunta es: ¿Puedo llamar voluntariamente al destructor para que me libere toda la memoria reservada para este polinomio?, porque al hacerlo manualmente simplemente copio el codigo del destructor. Así ahorraría bastante codigo.


Gracias y Saludos
Alguien sabe como hacer un buble que se repita segundos? o que tenga una frecuencia de 1Hz?

Lo estoy buscando mal por el google y solo encuentro el modo de poner el reloj mismo (el que da las horas xD)
Buenas tardes, tengo que hacer un proyecto de Informatica para dentro de unos dias, pero no logro sacar nada en claro de los ejercicios

http://www.lsi.upc.es/%7Emjserna/docencia/in1/T07/proyecto.pdf

Este es el enunciado entero..

El problema mayor viene dado en que los vectores/matrices y yo no somos muy amigos.

Si os lo mirais, vereis que esta relacionado con biologia y tal, por lo que tengo la ocurrencia de usar para cada grupo de 3 bases nitrogenadas (a, c, g, t) un numero, es decir, si contamos a=0, c=1, g=2 y t=3 tenemos un numero en base 4 para cada grupo de 3, pasar el numero a base 10 y crear un nuevo vector con dichos numeros y a partir de ahi seguir con todo el proyecto.

Os pido ayuda porque no se muy bien como hacer estos procedimientos y tal

Gracias y Salu2 ;)
ZholvaX, maja la firma xD
ImagenImagen

Edito:

inport(#puerto) para recibir datos
outport(#puerto, dato) para envío de datos

con esto se envia y recibe del puerto paralelo, pero no lo entiendo... Para enviar pones el puerto y lo que quieres enviar... Pero para recibir ¿solo el puerto? Donde pones los valores que recibes?
SPINAKER escribió:Pero para recibir ¿solo el puerto? Donde pones los valores que recibes?


TuVariable = inport(num-puerto);
JanKusanagi escribió:
TuVariable = inport(num-puerto);


unsigned long salida , entrada=0;
int puerto=0x378;
cout << "Numero de leds a encender :";

cin >> salida; //00 ; 01 ; 10 ; 11.

// verificar salida del puerto paralelo. Normalmente 0x378 //

(oup32)(0x378 , salida);

// Con esto se reciben valores del puerto //

entrada =(inp32)(puerto);
cout << "este es el valor captado :" << entrada <


Ahora el problema que tengo es que lo que envio por el puerto es lo que recibo xD Incluso teniendo los hilos de entrada al aire xD

alguna sugerencia?

Otra cosa, como se hace un bucle con un timer? que se repita cada segundo por ejemplo.

Yo vengo de Visual Basic, con lo cual estoy acostumbrado a tener ventanitas Windows y no las cutres de la consola, es complicado crear ventanitas con el c++? Algun tuto?

Otra cosa, hay alguna forma de introducir valores al "vuelo", ahora uso en "cin" y se queda quieto hasta que le doy al enter, no hay alguna forma de hacer que valla sin pararse?
No consigo sacar una mierda en claro [buuuaaaa]


Mañana os busco algunos (MSN o jabber) a ver si me podeis echar una mano
[bye]
Alguien me puede ayudar con este ejercicio simple de C?

Implementar una función que muestre un triángulo de la altura indicada
Ejemplo: Si se realiza la siguiente llamada: Triangulo(4), mostraria
*
**
***
****


Lo unico que se me ocurrio fue esto pero no me sale el TRIANGULO

#include<stdio.h>
#include<stdlib.h>
void triangulo(int);
main()
{
     int h;
     printf("Introduce un altura:\n");
     scanf("%d",&h);
     triangulo(h);
     system("PAUSE");
     }
     void triangulo (int  x)
     {
     int cont,linea;
     for(linea=0;linea<x;linea++)
     {
     printf("*");
     for(cont=0;cont<x;cont++)
     printf("\n");
     }
     return;
     }

Mañana tengo examen de practicas y basta que no sepa hacer este para que nos lo metan.

GRACIAS por adelantado!
BiOhAzArD-Zero escribió:Alguien me puede ayudar con este ejercicio simple de C?

Implementar una función que muestre un triángulo de la altura indicada
Ejemplo: Si se realiza la siguiente llamada: Triangulo(4), mostraria
*
**
***
****


Lo unico que se me ocurrio fue esto pero no me sale el TRIANGULO

#include
#include
void triangulo(int);
main()
{
int h;
printf("Introduce un altura:\n");
scanf("%d",&h);
triangulo(h);
system("PAUSE");
}
void triangulo (int x)
{
int cont,linea;
for(linea=0;linea {
printf("*");
for(cont=0;cont printf("\n");
}
return;
}

Mañana tengo examen de practicas y basta que no sepa hacer este para que nos lo metan.

GRACIAS por adelantado!


Primero deberías poner bien el código, utiliza el tag [*CODE][*/CODE] (sin asterísco), que no se entiende nada.

Quedaría con un par de modificaciones así:
#include<stdio.h>
#include<stdlib.h>

void triangulo(int x);

int main(int argc, char *argv[])
{
   int h;

   printf("Introduce un altura:\n");
   scanf("%d", &h);
   triangulo(h);

   return 0;
}

void triangulo(int x)
{
   int cont, linea;

   for(linea = 0; linea < x; linea++)
   {
      printf("*");
      for(cont = 0; cont < x; cont++)
         printf("\n");
   }
   return;
}


Por cada línea que pintas, escribes sólo un asterísco y tantos \n como número de línea estés. Arregla el problema por tí mismo, ya sabes donde está el error.

Cuando resuelvas el primer error te saldrá otro y es que pintarás siempre el mismo número de asteriscos por línea y finalmente llegarás al punto en el que pintas una línea menos de las que quieres pintar.

Fíjate en los índices que usas.

Un saludo.
Al final solo tenia que modificar un par de cosas. Queda asi:

#include<stdio.h>
#include<stdlib.h>
void triangulo(int);
main()
{
     int h;
     printf("Introduce un altura:\n");
     scanf("%d",&h);
     triangulo(h);
     system("PAUSE");
     }
     void triangulo (int  x)
     {
     int cont,linea;
     for(linea=0;linea<x;linea++)
     {
     for(cont=0;cont<=linea;cont++)
     printf("*");
     printf("\n");
     }
     return;
     }


Jaime para que declaraste más variables? Que solucion tenias pensada?
BiOhAzArD-Zero escribió:Al final solo tenia que modificar un par de cosas. Queda asi:

#include<stdio.h>
#include<stdlib.h>
void triangulo(int);
main()
{
     int h;
     printf("Introduce un altura:\n");
     scanf("%d",&h);
     triangulo(h);
     system("PAUSE");
     }
     void triangulo (int  x)
     {
     int cont,linea;
     for(linea=0;linea<x;linea++)
     {
     for(cont=0;cont<=linea;cont++)
     printf("*");
     printf("\n");
     }
     return;
     }


Jaime para que declaraste más variables? Que solucion tenias pensada?


Solo un par de consejos:

-Cuando declaras la funcion void triangulo(int); pon una variable, por ejemplo void triangulo(int a);
-Cuando la funcion es void triangulo(int a) no hace falta que pongas return;.

saludos
nobi escribió:
Solo un par de consejos:

-Cuando declaras la funcion void triangulo(int); pon una variable, por ejemplo void triangulo(int a);
-Cuando la funcion es void triangulo(int a) no hace falta que pongas return;.

saludos


E indenta el código, que si no es ilegible :p (prueba la utilidad indent)
BiOhAzArD-Zero escribió:Jaime para que declaraste más variables? Que solucion tenias pensada?


No he declarado ninguna variable más. Lo único que he hecho ha sido indentarlo un poco, hay varios posts de los gurús del foro que hablan de como hacerlo, pero a simple vista separa con un espacio las variables de los operandores, tabula cada bucle y separa los for, if, while, etc del paréntesis para diferenciarlos de las llamadas a funciones. Por ejemplo,

if(a<b){
a=b;
}else a=0;
funcion(a,b);

queda más claro así:
if (a < b) { /* Separa el if del parentesis */
   a = b;
}
else
   a = 0;
funcion(a, b); /* Sin espacios entre la funcion y sus argumentos y separando los argumentos con coma-espacio */


Cuando dices que añado variables, lo único que hago es definir el main para poder leer los argumentos. En tu caso no es necesario pero al final todos tus 'mains' acabarán usando argumentos y devolviendo algo al sistema así que usa mejor esta declaración:

int main(int argc, char *argv[]) {
   return 0;
}


Un saludo.
Yo tengo una duda con un ejercicio que tengo que hacer...

Es de forma recursiva y tengo que tratar de hacer una función que reciba dos argumentos, uno real y otro entero, el real será la base de la potencia y el entero será el exponente.

En la función lo que tengo que hacer es elevarlo y devolver el resultado. Pues tengo este código:

#include
#include

double elevar (double a, int b);

int main (void)

{
double a;
int b;
double r;

printf("escriba el numero base:");
scanf ("%d", &a);
fflush(stdin);

printf("escriba el numero exponente:");
scanf ("%i", &b);
fflush(stdin);

r = elevar (a, b);

printf("el resultado es: %lf\n", r);

system ("pause");
}

double elevar (double a, int b)

{
double resul;

if (b == 0)
{
return resul;
}
else {
resul = 1;
resul = resul * a;
b = b - 1;
return elevar (a, b);
}

}

El resultado final me da 0.0000000 si pongo 2 elevado a 3, y si pruebo con números más altos, me sale un número bastante largo de cifras que no tienen nada que ver.


Creo que hay vaarios problemas por el algoritmo, pero no caigo en cómo solucionarlos.


¡Ayuda!


EDITO: Y otra cosita, en mi compilador (DevC++) no hay ningun manual para mirar todas las librerias, todos los comandos, su forma de uso y demas???

Gracias.
Hay alguna forma de coger las teclas al vuelo?

Me refiero a como lo hacen los juegos por ejemplo, que no sea necesario apretar la tecla y darle al enter.
dandorf escribió:Yo tengo una duda con un ejercicio que tengo que hacer...

Es de forma recursiva y tengo que tratar de hacer una función que reciba dos argumentos, uno real y otro entero, el real será la base de la potencia y el entero será el exponente.

En la función lo que tengo que hacer es elevarlo y devolver el resultado. Pues tengo este código:

#include
#include

double elevar (double a, int b);

int main (void)

{
double a;
int b;
double r;

printf("escriba el numero base:");
scanf ("%d", &a);
fflush(stdin);

printf("escriba el numero exponente:");
scanf ("%i", &b);
fflush(stdin);

r = elevar (a, b);

printf("el resultado es: %lf\n", r);

system ("pause");
}

double elevar (double a, int b)

{
double resul;

if (b == 0)
{
return resul;
}
else {
resul = 1;
resul = resul * a;
b = b - 1;
return elevar (a, b);
}

}

El resultado final me da 0.0000000 si pongo 2 elevado a 3, y si pruebo con números más altos, me sale un número bastante largo de cifras que no tienen nada que ver.


Creo que hay vaarios problemas por el algoritmo, pero no caigo en cómo solucionarlos.


¡Ayuda!


EDITO: Y otra cosita, en mi compilador (DevC++) no hay ningun manual para mirar todas las librerias, todos los comandos, su forma de uso y demas???

Gracias.


Si te has leido un poco el hilo, es más fácil ayudaros si indentais y encapsulais el código en el tag [*CODE], que para eso está.

Al acabar la recursividad se ejecuta la llamada return resul, que no tiene asignado ningún valor porque resul no esta ni inicializada, de ahí que te de valores tan aleatorios.

Primero hazte un pseudocódigo en un papel que veas que funciona y luego lo pasas a código.

Una pista, no necesitas resul para nada, a parte de que lo usas mal:
resul = 1;
resul = resul * a;


Un saludo.
Jaime escribió:
No he declarado ninguna variable más. Lo único que he hecho ha sido indentarlo un poco, hay varios posts de los gurús del foro que hablan de como hacerlo, pero a simple vista separa con un espacio las variables de los operandores, tabula cada bucle y separa los for, if, while, etc del paréntesis para diferenciarlos de las llamadas a funciones. Por ejemplo,

if(a<b){
a=b;
}else a=0;
funcion(a,b);

queda más claro así:
if (a < b) { /* Separa el if del parentesis */
   a = b;
}
else
   a = 0;
funcion(a, b); /* Sin espacios entre la funcion y sus argumentos y separando los argumentos con coma-espacio */


Cuando dices que añado variables, lo único que hago es definir el main para poder leer los argumentos. En tu caso no es necesario pero al final todos tus 'mains' acabarán usando argumentos y devolviendo algo al sistema así que usa mejor esta declaración:

int main(int argc, char *argv[]) {
   return 0;
}


Un saludo.


Quedaria mas claro:

if (a < b)
a = b;
else
a = 0;

a mi me parece vamos, la tabulacion es importante el (a=b y a=0 tabulados que no se porque no se ve en el mensaje).

saludos
nobi escribió:
Quedaria mas claro:

if (a < b)
a = b;
else
a = 0;

a mi me parece vamos, la tabulacion es importante el (a=b y a=0 tabulados que no se porque no se ve en el mensaje).

saludos


Ya, ya, era para poner un ejemplo de como se indenta un 'if' con corchetes.

Si pones el texto con la etiqueta [*CODE] te salen las tabulaciones.

Un saludo.
Jaime escribió:
Ya, ya, era para poner un ejemplo de como se indenta un 'if' con corchetes.

Si pones el texto con la etiqueta [*CODE] te salen las tabulaciones.

Un saludo.




Voy a probar lo de tabulacion.

gracias
A ver, aqui os traigo un ejercicio chorra pero que no me acaba de salir

Como puedo modificar este programa para que me pregunte si lo quiero volver a ejecutar y así sea?

Tengo esto:

#include<stdio.h>
#include<stdlib.h>
main()
{
      int contpos=0,contneg=0,conttotal,a;
      for(conttotal=0;conttotal<5;conttotal++)
      {
                                              printf("Introduce un entero:\n");
                                              scanf("%d",&a);
                                              if(a!=0 && a<0)
                                              {
                                              printf("Numero negativo\n");
                                              contneg++;
                                              }
                                              if(a!=0 && a>0)
                                              {
                                              printf("Numero positivo\n");
                                              contpos++;
                                              }
                                              if(a==0 || conttotal==4)
                                              printf("Has introducido %d positivos y %d negativos\n",contpos,contneg);
                                              }
                                              system("PAUSE");
                                              }
                                                     
Puedes encerrar el código del programa dentro de un bucle do-while que se irá ejecutando continuamente hasta que el usuario confirme que desea salir del programa:

#include<stdio.h>
#include<stdlib.h>

main()
{
   int contpos,contneg,conttotal,a;
   char continuar;
     
   do
   {
      contpos = 0;
      contneg = 0;
        
      for(conttotal=0;conttotal<5;conttotal++)
      {
         printf("Introduce un entero:\n");
         scanf("%d",&a);
         getchar(); //Añadir siempre después de un scanf para recoger el \n superfluo que devuelve esta función

         if(a!=0 && a<0)
         {
            printf("Numero negativo\n");
            contneg++;
         }
         
         if(a!=0 && a>0)
         {
            printf("Numero positivo\n");
            contpos++;
         }
         
         if(a==0 || conttotal==4)
            printf("Has introducido %d positivos y %d negativos\n",contpos,contneg);
      }
      
      //Preguntamos al usuario que desea hacer hasta que nos dé una de las dos opciones válidas: 's' ó 'n'
      do
      {
         printf("Ejecutar de nuevo? (s/n): ");
         continuar = getchar();
      }
      while(continuar != 's' && continuar != 'n');
      
   }
   //Si el usuario ha dicho que no desea continuar esta condición será falsa y saldremos del programa.
   //De lo contrario, volvemos al principio del bucle y se ejecuta todo de nuevo
   while(continuar == 's');
   
   system("PAUSE");
}
288 respuestas
1, 2, 3, 4, 5, 6