Seite 1 von 1

warum scheitert printf()?

Verfasst: Do Jan 11, 2018 8:04 pm
von powerschaf
Ich hab probiert wie doof...

Code: Alles auswählen

int main()
{
    char *y = NULL;
    printf("%s",y); /**geht**/

    char *i = "Hallo";
    strcpy(i, NULL);
    printf("%s",i); /**gehtnicht**/

}
Warum scheitert die printf() Ausgabe hier?
THX

Re: warum scheitert printf()?

Verfasst: Do Jan 11, 2018 8:25 pm
von powerschaf
Falls Jemand wissen möchte wozu ich es brauche.....
Klappt alles bis auf die Fehlrmldung und ich hab mir echt Müh geben :x

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>

// Wandelt einen gegebenen String in Großbuchstaben um.

void toUpperString(char *str)
{
    int i = 0;
    while (str[i])
    {
        putchar(toupper(str[i]));
        i++;
    }

}


// Wandelt einen gegebenen String in Kleinbuchstaben um.
void toLowerString(char *str)
{
    int i = 0;
    while (str[i])
    {
        putchar(tolower(str[i]));
        i++;
    }

}


// Wandelt Groß- in Kleinbuchstaben um und umgekehrt.
void toInverseString(char *str)
{
    int i = 0;
    while (str[i])
    {
        if (isupper(str[i]))
        {
            putchar(tolower(str[i]));
        }
        else
        {
            putchar(toupper(str[i]));
        }
        i++;
    }

    }

/** Konvertiert einen String sicher mittels einer gegebenen
Funktion. Ist der String str NULL, wird eine Fehlermeldung ausgegeben.
Ansonsten wird der String ausgegeben, mittels der gegebenen Funktion
konvertiert und dann wird der String ausgegeben.**/

void safeStringConverter(char* str, void (*conversionFunc)(char*))
{
    if (str == NULL)
    {
        printf("FEHLER");
        return;
    }

    else
    {
        printf("Stringname: %s\n",str);

    }

    if (conversionFunc == toUpperString)
    {
        toUpperString(str);
    }
    else if (conversionFunc == toLowerString)
    {
        toLowerString(str);
    }
    else if (conversionFunc == toInverseString)
    {
    toInverseString(str);
    }
    else
    {
        printf("FEHLER, Funktion nicht gefunden!");
        return;
    }




}

// Hauptprogramm

int main(int argc, const char * argv[])
{
    char s[64];

    printf("----------------------------------\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
    printf("Test(1) toUpperString:\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
    strcpy(s, "Ich muss noch wachsen");
    safeStringConverter(s, toUpperString);
    printf("\n----------------------------------\n\n");


    printf("----------------------------------\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
    printf("Test(2) toLowerString:\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
    strcpy(s, "HILFE ICH BIN ZU GROSS");
    safeStringConverter(s, toLowerString);
    printf("\n----------------------------------\n\n");

    printf("----------------------------------\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
    printf("Test(3) toInverseString:\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
    strcpy(s, "TAUSCHE mich");
    safeStringConverter(s, toInverseString);
    printf("\n----------------------------------\n\n");

     printf("----------------------------------\n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);
    printf("FEHLERPARAMTER TEST: \n");
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);
    strcpy(s,NULL);
    safeStringConverter(s, toUpperString);




    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);

    return EXIT_SUCCESS;
}

Re: warum scheitert printf()?

Verfasst: Do Jan 11, 2018 11:56 pm
von nufan
powerschaf hat geschrieben:

Code: Alles auswählen

    strcpy(i, NULL);
Warum scheitert die printf() Ausgabe hier?
Die printf()-Ausgabe scheitert nicht, sondern strcpy(). Du übergibst NULL als Quell-String für den Kopiervorgang. Die Funktion versucht an dieser Stelle Daten zu lesen und das Programm stürzt ab.

Du kannst das ganze unter Linux auch mit valgrind debuggen:

Code: Alles auswählen

$ valgrind ./a.out
[...]
==2901== Invalid read of size 1
==2901==    at 0x4F7D260: __strcpy_ssse3 (in /usr/lib/libc-2.26.so)
==2901==    by 0x1086DD: main (in /tmp/a.out)
==2901==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
[...]

Re: warum scheitert printf()?

Verfasst: Fr Jan 12, 2018 8:36 am
von powerschaf
Ja habe die Lösung... ich übergebe NULL direkt in der Funktion safeStringcopy(NULL, funktion)... das strcpy fällt weg.

Re: warum scheitert printf()?

Verfasst: Fr Jan 12, 2018 10:57 am
von mfro
powerschaf hat geschrieben:

Code: Alles auswählen

...
    if (conversionFunc == toUpperString)
    {
        toUpperString(str);
    }
    else if (conversionFunc == toLowerString)
    {
        toLowerString(str);
    }
    else if (conversionFunc == toInverseString)
    {
    toInverseString(str);
    }
    else
    {
        printf("FEHLER, Funktion nicht gefunden!");
        return;
    }
Wozu soll das gut sein? Wenn Du nur *genau die* Stringkonvertierungen zulassen willst, macht es keinen Sinn, einen Funktionszeiger zu übergeben (der ist ja gerade dazu gedacht, eine Funktion aufrufen zu können, an die beim Entwurf noch nicht gedacht war). Wenn das also eingeschränkt sein soll, wäre so was hier m.E. besser:

Code: Alles auswählen

enum conversion { TOUPPER, TOLOWER, TOINVERSE } cv;

void safeStringConverter(char* str, enum conversion cv)
{
    switch (cv)
    {
        case TOUPPER:
            toUpperStr(str);
            break;
       case TOLOWER:
            toLowerStr(str);
            break;
    ....
    }
}
Wenn Du dir hingegen die Flexibilität erhalten willst, neue Konvertierungen hinzuzufügen ohne existierenden Code ändern zu müssen, solltest Du direkt den Funktionszeiger aufrufen:

Code: Alles auswählen

    if (conversionFunc)
       (*conversionFunc)(str);
und dem Aufrufer vertrauen, dass er eine vernünftige Funktion bereitstellt. Deins ist eine Mischung aus beidem (und vereint m.E. die Nachteile), jeder, der das liest wird sich fragen: was macht er denn da?