Hoe een string herhalen in C?

Op dit moment probeer ik dit:

#include <stdio.h>
int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
    }
    else {
        char source[] = "This is an example.";
        int i;
        for (i = 0; i < sizeof(source); i++) {
            printf("%c", source[i]);
        }
    }
    getchar();
    return 0;
}

Dit werkt ook NIET:

char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
    printf("%c", source[i]);
}

Ik krijg de foutmelding

Onverwerkte uitzondering op 0x5bf714cf (msvcr100d.dll) in Test.exe: 0xC0000005: toegangsfout tijdens lezen op positie 0x00000054.

(vrij vertaald uit het Duits)

Dus wat is er mis met mijn code?


Antwoord 1, autoriteit 100%

Je wilt:

for (i = 0; i < strlen(source); i++) {

sizeof geeft je de grootte van de aanwijzer, niet de string. Het zou echter hebben gewerkt als u de aanwijzer als een array had gedeclareerd:

char source[] = "This is an example.";

maar als je de array doorgeeft aan function, vervalt ook dat naar een pointer. Voor snaren kun je het beste altijd strlen gebruiken. En let op wat anderen hebben gezegd over het wijzigen van printf om %c te gebruiken. En ook, rekening houdend met de opmerkingen van mmyers over efficiëntie, zou het beter zijn om de oproep naar strlen uit de lus te verplaatsen:

int len = strlen(source);
for (i = 0; i < len; i++) {

of herschrijf de lus:

for (i = 0; source[i] != 0; i++) {

Antwoord 2, autoriteit 69%

Een veelgebruikt idioom is:

char* c = source;
while (*c) putchar(*c++);

Een paar opmerkingen:

  • In C zijn strings null-terminated. Je herhaalt terwijl het gelezen teken niet het nulteken is.
  • *c++verhoogt cen retourneert de verwijderde oudewaarde van c.
  • printf("%s")drukt een null-terminated string af, geen char. Dit is de oorzaak van uw toegangsschending.

Antwoord 3, autoriteit 6%

In plaats van strlen te gebruiken zoals hierboven gesuggereerd, kunt u gewoon controleren op het NULL-teken:

#include <stdio.h>
int main(int argc, char *argv[])
{
    const char *const pszSource = "This is an example.";
    const char *pszChar = pszSource;
    while (pszChar != NULL && *pszChar != '\0')
    {
        printf("%s", *pszChar);
        ++pszChar;
    }
    getchar();
    return 0;
}

Antwoord 4, autoriteit 4%

Een geoptimaliseerde aanpak:

for (char character = *string; character != '\0'; character = *++string)
{
    putchar(character); // Do something with character.
}

De meeste C-strings hebben een null-terminatie, wat betekent dat zodra het teken een '\0'wordt, de lus moet stoppen. De *++stringverplaatst de aanwijzer één byte, dereferentie en de lus herhaalt zich.

De reden waarom dit efficiënter is dan strlen()is omdat strlen al door de string loopt om de lengte te vinden, dus je zou in feite twee keer herhalen (één keer meer dan nodig) met strlen().


Antwoord 5, autoriteit 3%

sizeof(source)retourneert het aantal bytes dat vereist is voor de pointer char*. Je moet het vervangen door strlen(source), wat de lengte is van de string die je probeert weer te geven.

U moet waarschijnlijk printf("%s",source[i])vervangen door printf("%c",source[i])aangezien u laat een karakter zien.


Antwoord 6, autoriteit 3%

  1. sizeof() bevat het afsluitende null-teken. Je zou strlen() moeten gebruiken (maar de aanroep buiten de lus plaatsen en opslaan in een variabele), maar dat is waarschijnlijk niet de oorzaak van de uitzondering.
  2. je moet “%c” gebruiken, niet “%s” in printf – je drukt een karakter af, geen string.

Antwoord 7, autoriteit 3%

Dit zou moeten werken

#include <stdio.h>
 #include <string.h>
 int main(int argc, char *argv[]){
    char *source = "This is an example.";
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation
    for (int i = 0; i < length; i++) 
    {
       printf("%c", source[i]);
    }
 }

Antwoord 8

  • sizeof(source)geeft je de grootte van een char*terug, niet de lengte van de string. Je zou strlen(source)moeten gebruiken, en je zou dat uit de lus moeten halen, anders bereken je de grootte van de string elke lus opnieuw.
  • Door af te drukken met de %sformaatmodifier, zoekt printfnaar een char*, maar je geeft eigenlijk een char. U moet de modifier %cgebruiken.

Antwoord 9

Verander gewoon de grootte van met strlen.

Zoals dit:

char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
    printf("%c", source[i]);
}

Antwoord 10

De laatste index van een C-string is altijd de integerwaarde 0, vandaar de frase “null-beëindigde string”. Aangezien integer 0 hetzelfde is als de Booleaanse waarde false in C, kun je dat gebruiken om een eenvoudige while-clausule te maken voor je for-lus. Wanneer het de laatste index bereikt, zal het een nul vinden en dat gelijkstellen aan false, waardoor de for-lus wordt beëindigd.

for(int i = 0; string[i]; i++) { printf("Char at position %d is %c\n", i, string[i]); }

Antwoord 11

Vervang sizeof door strlen en het zou moeten werken.


Antwoord 12

sizeof(source)retourneert sizeof een pointer als de bron wordt gedeclareerd als char *.
De juiste manier om het te gebruiken is strlen(source).

Volgende:

printf("%s",source[i]); 

verwacht string. d.w.z. %s verwacht een tekenreeks, maar u itereert in een lus om elk teken af te drukken. Gebruik daarom %c.

Uw manier van toegang tot (itereren) van een string met behulp van de index i is echter correct en daarom zijn er geen andere problemen.

Other episodes