Asignación hace puntero desde entero sin molde

Viniendo de un fondo de Java, estoy aprendiendo C, pero encuentro estos vagos mensajes de error de comstackción cada vez más frustrantes. Aquí está mi código:

/* * PURPOSE * Do case-insensetive string comparison. */ #include  #include  #include  int compareString(char cString1[], char cString2[]); char strToLower(char cString[]); int main() { // Declarations char cString1[50], cString2[50]; int isEqual; // Input puts("Enter string 1: "); gets(cString1); puts("Enter string 2: "); gets(cString2); // Call isEqual = compareString(cString1, cString2); if (isEqual == 0) printf("Equal!\n"); else printf("Not equal!\n"); return 0; } // WATCH OUT // This method *will* modify its input arrays. int compareString(char cString1[], char cString2[]) { // To lowercase cString1 = strToLower(cString1); cString2 = strToLower(cString2); // Do regular strcmp return strcmp(cString1, cString2); } // WATCH OUT // This method *will* modify its input arrays. char strToLower(char cString[]) { // Declarations int iTeller; for (iTeller = 0; cString[iTeller] != '\0'; iTeller++) cString[iTeller] = (char)tolower(cString[iTeller]); return cString; } 

Esto genera dos advertencias.

  • asignación hace puntero de entero sin un molde
    • cString1 = strToLower (cString1);
    • cString2 = strToLower (cString2);
  • return crea un entero desde el puntero sin un molde
    • devolver cString;

¿Alguien puede explicar estas advertencias?

Las cadenas C no se parecen en nada a las cadenas Java. Son esencialmente matrices de caracteres.

Está recibiendo el error porque strToLower devuelve un char. Un char es una forma de entero en C. Lo está asignando en un char [] que es un puntero. Por lo tanto, “convertir entero en puntero”.

Su strToLower hace todos sus cambios en su lugar, no hay razón para que devuelva nada, especialmente no un char. Deberías “devolver” el vacío, o un char *.

En la llamada a strToLower, tampoco hay necesidad de asignación, básicamente está pasando la dirección de memoria para cString1.

En mi experiencia, Strings in C es la parte más difícil de aprender para cualquier persona que venga del fondo Java / C # a C. La gente puede llevarse bien con la asignación de memoria (ya que incluso en Java a menudo se asignan matrices). Si su objective final es C ++ y no C, es posible que prefiera concentrarse menos en las cadenas C, asegúrese de comprender los conceptos básicos y simplemente utilice la cadena C ++ de STL.

El tipo de devolución de strToLower debe ser char* not char (o no debe devolver nada en absoluto, ya que no vuelve a asignar la cadena)

Como ya se señaló, en un caso está intentando devolver cString (que es un valor char * en este contexto, un puntero) de una función que se declara para devolver un char (que es un número entero). En otro caso, haga lo contrario: está asignando un valor de retorno de char a un puntero char * . Esto es lo que desencadena las advertencias. Sin duda debe declarar sus valores de devolución como char * , no como char .

Nótese por cierto que estas asignaciones son de hecho violaciones de restricción desde el punto de vista del lenguaje (es decir, son “errores”), ya que es ilegal mezclar punteros y enteros en C de ese modo (aparte del cero constante integral). Su comstackdor simplemente es demasiado indulgente en este aspecto e informa estas violaciones como meras “advertencias”.

Lo que también quería señalar es que en varias respuestas podría notar la sugerencia relativamente extraña de devolver el void de sus funciones, ya que está modificando la cadena en el lugar. Si bien funcionará (ya que de hecho está modificando la cadena en el lugar), no hay nada realmente malo en devolver el mismo valor de la función. De hecho, es una práctica bastante estándar en el lenguaje C cuando corresponde (eche un vistazo a las funciones estándar como strcpy y otros), ya que habilita el “encadenamiento” de llamadas a función si elige usarlo, y no cuesta prácticamente nada si no use “encadenamiento”.

Dicho esto, las asignaciones en su implementación de compareString parecen superfluas (a pesar de que no romperán nada). Me desharía de ellos

 int compareString(char cString1[], char cString2[]) { // To lowercase strToLower(cString1); strToLower(cString2); // Do regular strcmp return strcmp(cString1, cString2); } 

o usa “encadenamiento” y hazlo

 int compareString(char cString1[], char cString2[]) { return strcmp(strToLower(cString1), strToLower(cString2)); } 

(Aquí es cuando su retorno de char * sería útil). Solo tenga en cuenta que las llamadas a funciones “encadenadas” a veces son difíciles de depurar con un depurador paso a paso.

Como nota adicional no realizada, diría que implementar una función de comparación de cadenas de una manera tan destructiva ( modifica las cadenas de entrada) podría no ser la mejor idea. Una función no destructiva sería de mucho mayor valor en mi opinión. En lugar de realizar una conversión explícita de las cadenas de entrada a minúsculas, generalmente es una mejor idea implementar una función de comparación de cadenas insensible a las mayúsculas y minúsculas personalizada y usarla en lugar de llamar al strcmp estándar.

  • 1) No usar gets ! Está introduciendo una vulnerabilidad de desbordamiento de búfer. Use fgets(..., stdin) lugar.

  • 2) En strToLower estás devolviendo un char lugar de un char -ray. O bien devuelve char* como se sugiere Autopulated, o simplemente devuelve void ya que está modificando la entrada de todos modos. Como resultado, solo escriba

  strToLower(cString1); strToLower(cString2); 
  • 3) Para comparar cadenas que no distinguen entre mayúsculas y minúsculas, puede usar strcasecmp (Linux y Mac) o stricmp (Windows).

No necesita estas dos asignaciones:

 cString1 = strToLower(cString1); cString2 = strToLower(cString2); 

estás modificando las cuerdas en su lugar.

Las advertencias se deben a que está devolviendo un char y asignando un char [] (que es equivalente a char *)

Está devolviendo char, y no char *, que es el puntero al primer carácter de una matriz.

Si desea devolver una nueva matriz de caracteres en lugar de realizar modificaciones in situ, puede solicitar un puntero ya asignado (char *) como parámetro o un puntero no inicializado. En este último caso, debe asignar el número adecuado de caracteres para la nueva cadena y recordar que en los parámetros C se pasa por el valor SIEMPRE, por lo que debe usar el parámetro char ** como en el caso de la matriz asignada internamente por la función. Por supuesto, el que llama debe liberar ese puntero más tarde.

strToLower debería devolver un char * en lugar de un char. Algo como esto haría.

 char *strToLower(char *cString) 
 char cString1[] 

Esta es una matriz, es decir, un puntero al primer elemento de un rango de elementos del mismo tipo de datos. Tenga en cuenta que no está pasando el valor por defecto de la matriz, sino por el puntero.

 char strToLower(...) 

Sin embargo, esto devuelve un char. Entonces tu tarea

 cString1 = strToLower(cString1); 

tiene diferentes tipos en cada lado del operador de asignación … en realidad estás asignando un ‘char’ (tipo de entero) a una matriz, que se convierte en un simple puntero. Debido a las reglas de conversión implícitas de C ++, esto funciona, pero el resultado es basura y un mayor acceso a la matriz provoca un comportamiento indefinido.

La solución es hacer que strToLower devuelva char* .