Opdracht maakt aanwijzer van gehele getal zonder cast

Komend van een Java-achtergrond Ik ben aan het leren C, maar ik vind die vage compiler-foutmeldingen steeds meer frustrerend. Hier is mijn code:

/*
 * PURPOSE
 *      Do case-insensetive string comparison.
 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
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;
}

Dit genereert twee waarschuwingen.

  • Toewijzing maakt aanwijzer vanaf geheel getal zonder een cast
    • CSTRING1 = STRTRTROOWER (CSTRING1);
    • CSTRING2 = STRTRTROOWER (CSTRING2);
  • Return maakt integer uit de aanwijzer zonder een cast
    • Terugkeer CSTRING;

Kan iemand deze waarschuwingen uitleggen?


1, Autoriteit 100%

C-strings zijn niet zoiets als Java-strings. Het zijn in wezen arrays van karakters.

Je krijgt de foutmelding omdat strToLower een char retourneert. Een char is een vorm van een geheel getal in C. Je wijst het toe aan een char [] die een pointer is. Vandaar “converting integer to pointer”.

Uw strToLower brengt al zijn wijzigingen aan, er is geen reden om iets terug te geven, vooral geen char. U moet ongeldig “retourneren”, of een char*.

Bij de aanroep van strToLower is er ook geen toewijzing nodig, u geeft in wezen alleen het geheugenadres door voor cString1.

In mijn ervaring zijn strings in C het moeilijkste deel om te leren voor iedereen die van Java/C#-achtergrond terug naar C komt. Mensen kunnen goed overweg met geheugentoewijzing (aangezien je zelfs in Java vaak arrays toewijst). Als uw uiteindelijke doel C++ is en niet C, kunt u zich misschien liever minder concentreren op C-strings, zorg ervoor dat u de basis begrijpt en gebruik gewoon de C++-string van STL.


Antwoord 2, autoriteit 15%

Het retourtype van

strToLower moet char*zijn en niet char
(of het zou helemaal niets moeten retourneren, omdat het de string niet opnieuw toewijst)


Antwoord 3, autoriteit 5%

  • 1) Gebruik geen gets! Je introduceert een buffer-overflow-kwetsbaarheid. Gebruik in plaats daarvan fgets(..., stdin).

  • 2) In strToLowerretourneert u een charin plaats van een char-array. Retourneer char*zoals Autopulated suggereerde, of retourneer gewoon voidomdat je de invoer toch aan het wijzigen bent. Schrijf daarom gewoon

 

strToLower(cString1);
 strToLower(cString2);
  • 3) Om hoofdletterongevoelige tekenreeksen te vergelijken, kunt u strcasecmp(Linux & Mac) of stricmp(Windows) gebruiken.

4

U hebt deze twee bijvoers niet nodig:

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

U wijzigt de strings op zijn plaats.

Waarschuwingen zijn omdat u een Char retourneert en toewijst aan een Char [] (die gelijk is aan CHAR *)


5

U retourneert Char, en niet Char *, dat is de aanwijzer naar het eerste teken van een array.

Als u een nieuwe tekenreeks wilt retourneren in plaats van wijzigingen ter plaatse uit te voeren, kunt u vragen om een reeds toegewezen aanwijzer (char*) als parameter of om een niet-geïnitialiseerde aanwijzer. In dit laatste geval moet u het juiste aantal tekens toewijzen voor een nieuwe string en onthoud dat in C parameters zoals doorgegeven door waarde ALTIJD, dus u moet char** gebruiken als parameter in het geval van een intern toegewezen array door functie. Natuurlijk moet de beller die aanwijzer later vrijgeven.


Antwoord 6

strToLower zou een char * moeten retourneren in plaats van een char. Zoiets zou voldoende zijn.

char *strToLower(char *cString)

Antwoord 7

char cString1[]

Dit is een array, d.w.z. een aanwijzer naar het eerste element van een reeks elementen van hetzelfde gegevenstype. Merk op dat je de array niet per waarde doorgeeft, maar per pointer.

char strToLower(...)

Dit retourneert echter een char. Dus jouw opdracht

cString1 = strToLower(cString1);

heeft verschillende typen aan elke kant van de toewijzingsoperator .. je wijst eigenlijk een ‘char’ (soort geheel getal) toe aan een array, die wordt omgezet in een eenvoudige aanwijzer. Dankzij de impliciete conversieregels van C++ werkt dit, maar het resultaat isonzin en verdere toegang tot de array veroorzaakt ongedefinieerd gedrag.

De oplossing is om strToLowerchar*te laten retourneren.

Other episodes