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 daarvanfgets(..., stdin)
. -
2) In
strToLower
retourneert u eenchar
in plaats van eenchar
-array. Retourneerchar*
zoals Autopulated suggereerde, of retourneer gewoonvoid
omdat 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) ofstricmp
(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 strToLower
char*
te laten retourneren.