0

Estaba programando y he tenido una duda al hacer un condicional , ¿alguien me puede decir porque no me reconoce los valores que he puesto en el if(A==...)?

printf("Fichero con cosas, quiere escrbir algo mas o hacer uno nuevo:");
scanf("%s",A);
if(A =='a')
{
    f2=fopen(archivo2,"a");
}
if(A=='w')
{
    f2=fopen(archivo2,"w");
}
MrDave1999
  • 7,491
  • 1
  • 7
  • 22
Wow
  • 101
  • 4

2 Answers2

2
scanf("%s", A);

no lee un caracter, lee una cadena.

Además, para que scanf te meta el valor que lee en A, debes pasarle la dirección de A.

scanf("%c", &A);

Si haces

char cadena[5];
scanf("%s", cadena);

esto funciona porque cadena sin subíndices ya es la dirección del array (más concretamente la del primer elemento).

SJuan76
  • 10,771
  • 5
  • 17
  • 31
  • Si , lo tenia igual que me dices tu , lo siento igual no me explique bien , lo que me pasa es que al poner if(A==(valor de scanf)) no se como poner "valor de scanf" para que cuando lo ponga lo identifique – Wow Aug 28 '20 at 12:52
  • @Wow realmente no te explicas ¿No es *A* es "valor de scanf"? – SJuan76 Aug 28 '20 at 13:08
  • A ver lo siento enserio , lo que necesito no es como poner scanf y tal porque eso me lo lee bien , lo que no me identifica es el condicional , me explico , yo quiero poner en el programa una "a" o "w" y que me haga una de las dos cosas segun lo que ponga en cada parte , pero no se como ponerlo para que me lo recoja en el if, yo he puesto A=='w' , pero no funciona – Wow Aug 28 '20 at 13:15
  • Debería funcionar. Haz un *printf* del valor de A para ver qué se guarda. – SJuan76 Aug 28 '20 at 13:19
  • Si eso es lo que hice pero al hacer el printf , me sale el valor que habia puesto en el scanf asi que supongo que no es ese el problema – Wow Aug 28 '20 at 13:25
  • No tiene sentido. ¿Puedes poner el ejemplo **completo** tal como dices que lo tienes, en vez de decir "lo tenía así" o "lo tenía asá"? Dale al botón de "editar." – SJuan76 Aug 28 '20 at 13:49
2

¿Por qué el resultado de la condición es falso cuando comparo caracteres?

Miremos el siguiente código:

#include <stdio.h>

int main(void)
{
    char A[2];
    printf("Fichero con cosas, quiere escrbir algo mas o hacer uno nuevo:");
    scanf("%s", A);
    if(A=='a')
    {
        f2=fopen(archivo2,"a");
    }
    if(A=='w')
    {
        f2=fopen(archivo2,"w");
    }
    return 0;
}

En este ejemplo, declaro un array de 2 elementos y le pedimos al usuario una cadena, aunque en realidad el usuario solo debería de ingresar únicamente un caracter.

Entonces, sí el usuario teclea la letra a, este caracter estará guardado en la posición 0 (aunque en realidad lo que se guarda es el código ASCII del caracter) del array.

scanf se encargará que el caracter nulo (indica el fin de la cadena) esté en la posición 1.

Hasta ahí, no hay problemas, pero cuando nos topamos en esta condición:

if(A=='a')

Nos damos cuenta que esa condición nunca se cumplirá, porque el identificador A, representa la dirección de memoria del primer elemento del array. Por lo tanto, estás comparando una dirección con un código ASCII (el de caracter 'a'). Esa es la razón del porque SIEMPRE da false la restricción.

Entonces lo que podrías hacer, es usar la función strcmp de la cabecera string.h:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char A[2];
    printf("Fichero con cosas, quiere escrbir algo mas o hacer uno nuevo:");
    scanf("%s", A);
    if(strcmp(A, "a") == 0)
    {
        f2=fopen(archivo2,"a");
    }
    if(strcmp(A, "w") == 0)
    {
        f2=fopen(archivo2,"w");
    }
    return 0;
}

De este modo, podrás comparar si dos cadenas son iguales. De igual manera, hay que evitar el desbordamiento de búfer en esta línea:

scanf("%s", A);

En el array A solo podemos guardar un caracter + el caracter nulo, así que si el usuario ingresa más de la cuenta, provocará un comportamiento indefinido, esto significa que el programa puede funcionar como no puede funcionar, el resultado es arbitrario.

Un posible resultado sería sobrescribir la memoria del propio programa. Otro resultado sería intentar leer o escribir en una dirección que ya es usado por otro proceso, ahí en ese caso, lo normal es que el sistema mate el proceso actual.

En fin, debes evitar el desbordamiento de esta manera:

//Sí el usuario ingresa más de 1 caracter, scanf solo leerá uno.
scanf("%1s", A);

En este hilo explico con más detalle como evitar el desbordamiento cuando pides una cadena con scanf.

Solución 2: En vez de pedir una cadena, podrías pedir únicamente un caracter:

#include <stdio.h>
#include <string.h>

int main(void)
{
    //En esta variable guardamos el caracter.
    char A;
    printf("Fichero con cosas, quiere escrbir algo mas o hacer uno nuevo:");
    //Hay que pasar la dirección de memoria de A
    scanf("%c", &A);
    //Ahora si podemos comparar códigos ASCII :)
    if(A == 'a')
    {
        f2=fopen(archivo2,"a");
    }
    //Ahora si podemos comparar códigos ASCII :)
    if(A == 'w')
    {
        f2=fopen(archivo2,"w");
    }
    return 0;
}

De este modo, nos evitamos tres cosas:

1.- No hay que preocuparse por el desbordamiento de búfer.

2.- No necesitamos usar la función strcmp.

3.- No hay que enfocarse en dejar un espacio para el caracter nulo.

MrDave1999
  • 7,491
  • 1
  • 7
  • 22