Seite 1 von 2

String Problem

Verfasst: Sa Okt 22, 2011 9:51 am
von Kmitska
Hallo,

Dieses Problem taucht mir immer wieder auf, kanns einfach nicht lösen! :X
Habe Probleme mit Funktionen die char* wieder geben.

Hier ist eine Funktion:

Code: Alles auswählen

char* GetValueName(char Content[])
{
    char ValueName[strlen(Content)];
    for(int i=0; i<=strlen(Content); i++)
    {
        if(Content[i] == '=')
        {
            return ValueName;
        }
        else
        if (Content[i] != '=')
        {
            strcat(ValueName, &Content[i]);
        }
    }
}
Beim Einsetzen:

Code: Alles auswählen

GetValueName("Name=Hallo");
und ich will ja eigentlich nur "Name" haben aber kriege irgendetwas anderes raus + Geräusch :/
Wäre sehr dankbar, wenn Ihr mir helfen könntet. :)

Mit freundlichen Grüßen.

Re: String Problem

Verfasst: Sa Okt 22, 2011 10:50 am
von Patrick_C64

Code: Alles auswählen

#include <stdio.h>
#include <string.h>

void GetValueName(char Content[], char *__rtn_string)
{
    int len = 0;

    for(int n=0; n<=strlen(Content); n++)
    {
            if (Content[n] == '=') {
            len = n;
            break;
            }
    }
    // kopieren des gewünschten bereichs
    memcpy (__rtn_string, Content, len);
    // mit 0 terminieren
    memset (__rtn_string+len,       0, 1);
}

int main () {

    char txt[200]; // ist nur hier gültig !! Bei verlassen der Function also futsch!
                        // kann aber per Pointer "rausgegeben" werden
    GetValueName ("name=testname",txt);
    printf("GET : %s\n",txt);

return 0;
}
ACHTUNG !! code dient nur der Veranschaulichung !!

Hi,

Deine Rückgabe ist auf dem Stack, du muss entweder auf dem Heap allozieren oder an die Verarbeitende Function einen Pointer auf den Stack mitgeben. Schau dir mal gültigkeitsbereiche von Variablen an (Scopes) und Stack und Heap.


mfg. Patrick_C64

Re: String Problem

Verfasst: Sa Okt 22, 2011 10:55 am
von cloidnerux

Code: Alles auswählen

strcat(ValueName, &Content[i]);
Woher hast du das? Das ist mal eben grob falsch.
strcat fügt strings zusammen, und strings sind immer "\0" Terminiert, das heißt, die Funktion wird so lange kopieren, bis sie ein "\0" findet.
Da du nun aber mit "&Content" der Funktion mitteilst, das sie an einer stelle im Array kopieren soll, wird das nix.
Einzelne Zeichen solltest du direkt anfügen, indem du die entsprechenden Indexoperatoren verwendest.
Zudem kannst du dir das zweite if sparen, denn wenn Content nicht gleich "=" ist, ist es immer ungleich "=", das aber nur am rande.
Zudem meine ich, das der string den du zurückgibst ebenfalls nicht Null-terminiert ist, sodass dein entsprechendes printf oder cout so lange aus dem Speicher versucht Zeichen auszulesen, bis er ein "\0" findet.
Hier wird das auch nochmal erklärt: http://www.proggen.org/doku.php?id=c:type:array

Strings sind halt etwas knifflig.

MfG cloidnerux.

Edit:
Deine Rückgabe ist auf dem Stack, du muss entweder auf dem Heap allozieren oder an die Verarbeitende Function einen Pointer auf den Stack mitgeben. Schau dir mal gültigkeitsbereiche von Variablen an (Scopes) und Stack und Heap.

Etwas kompliziert als ich es lösen würde, dafür aber Definitiv cooler.

Re: String Problem

Verfasst: Sa Okt 22, 2011 11:52 am
von Kmitska
Alsooo, erst mal bedanke ich mich für die schnelle Antworten :)

ich habe jetzt so etwas:

Code: Alles auswählen

char* GetValueName(char Content[])
{
    int len = 0;
    char ValueName[100];

    for(int i=0; i<=strlen(Content); i++)
    {
        if(Content[i] == '=')
        {
            len = (--i);
            break;
        }
        memcpy(ValueName, Content, len);
        return ValueName;
    }

}

was ist jetzt hier falsch? :/

Re: String Problem

Verfasst: Sa Okt 22, 2011 12:05 pm
von cloidnerux
was ist jetzt hier falsch? :/
Generell stellt sich mir die Frage, was denn bei dir nicht richtig läuft, weil das beim Fehler finden extremst helfen kann.
Da es höchstwarscheinlich immer noch dein Problem mit den merkwürdigen Zeichen ist, würde ich mal folgendes Suggerieren:

Code: Alles auswählen

memcpy(ValueName, Content, len);
ValueName[i] = "\0";    //0-Terminierung für den String, damit dien Computer weiß wann ende ist. (Keine garantie auf richtigen Index)
return ValueName;
Auch würde ich vorschlagen, das du dir mal Pointer ansiehst und die Funktion "malloc".
Dadurch kannst du Dynamisch speicher anfordern und so Probleme umgehen, wenn du mal Zeichenketten mit mehr als 100 Zeichen hast.

Re: String Problem

Verfasst: Sa Okt 22, 2011 12:40 pm
von Patrick_C64
1. Du erstellst ValueName in deiner Funktion!
2. Kopierst dann dort rein
3. returnst ValueName und verlässt die Funktion

Also mal ab von den anderen Fehlern im 1. Code das selbe in Grün *GRINS

Beim Verlassen der Function geht ValueName verloren da es nur in deiner Funktion gültig ist da kannst du 1000* Irgentwas reinkopieren :mrgreen: beim verlassen der Funktion (des Scopes) ist ValueName futsch, kann passieren das du dennoch mal mit viel Glück das bekommst was du wolltest aber da dein Speicher wieder frei oder gar schon neu beansprucht wurde, wird ein Zugriff auf diesen in Undefinierten Zuständen enden.


Heap, Stack, Scopes !!!

mfg. Patrick_C64

Re: String Problem

Verfasst: Sa Okt 22, 2011 1:13 pm
von Kmitska

Code: Alles auswählen

void GetValueName(char Content[], char* ValueName)
{
    int len = 0;
    for(int i=0; i<=strlen(Content); i++)
    {
        if(Content[i] == '=')
        {
            len = i;
            break;
        }
        memcpy(ValueName, Content, len);
    }
}
und main.cpp:

Code: Alles auswählen

int main(void)
{
    char Nick[] = "Name=Hallo";
    char* pointer = new char;
    GetValueName(Nick, pointer);
    cout << *pointer;
    delete pointer;
    return 0;
}
diese Funktion nervt langsam...

Re: String Problem

Verfasst: Sa Okt 22, 2011 1:18 pm
von MoonGuy
Patrick_C64 hat geschrieben:1. Du erstellst ValueName in deiner Funktion!
2. Kopierst dann dort rein
3. returnst ValueName und verlässt die Funktion

Also mal ab von den anderen Fehlern im 1. Code das selbe in Grün *GRINS

Beim Verlassen der Function geht ValueName verloren da es nur in deiner Funktion gültig ist da kannst du 1000* Irgentwas reinkopieren :mrgreen: beim verlassen der Funktion (des Scopes) ist ValueName futsch, kann passieren das du dennoch mal mit viel Glück das bekommst was du wolltest aber da dein Speicher wieder frei oder gar schon neu beansprucht wurde, wird ein Zugriff auf diesen in Undefinierten Zuständen enden.


Heap, Stack, Scopes !!!

mfg. Patrick_C64
Das sagt mir mein Compiler: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben. Ist ein Warning, aber dennoch zu beachten!
Um das alles zu umgehen, musst du bei Patricks Rat zwischen den Zeilen lesen. Du musst ValueName als Pointer initialisieren und Speicherplatz reservieren. Dann kannst du damit auch außerhalb der Funktion weiterarbeiten.

€dit:
Kmitska hat geschrieben:

Code: Alles auswählen

void GetValueName(char Content[], char* ValueName)
{
    int len = 0;
    for(int i=0; i<=strlen(Content); i++)
    {
        if(Content[i] == '=')
        {
            len = i;
            break;
        }
        memcpy(ValueName, Content, len);
    }
}
und main.cpp:

Code: Alles auswählen

int main(void)
{
    char Nick[] = "Name=Hallo";
    char* pointer = new char;
    GetValueName(Nick, pointer);
    cout << *pointer;
    delete pointer;
    return 0;
}
diese Funktion nervt langsam...
Jetzt schreibst du deine Funktion um. Du reservierst 1 Byte Speicher: "char* pointer = new char;", aber willst ganz viel reinkopieren: "memcpy(ValueName, Content, len);". Das geht auch nicht!

Re: String Problem

Verfasst: Sa Okt 22, 2011 1:38 pm
von Patrick_C64
@Moonguy,

hehe ok hast recht aber ganz Ehrlich, in die Richtung hatte ich garnicht gedacht, aber gut auch hierzu die "Lösung" bzw. ein "Denkanstoss" :) .

Code: Alles auswählen

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

void GetValueName(char Content[], char *__rtn_string)
{
    int len = 0;

    for(int n=0; n<=strlen(Content); n++)
    {
            if (Content[n] == '=') {
            len = n;
            break;
            }
    }
    // kopieren des gewünschten bereichs
    memcpy (__rtn_string, Content, len);
    // mit 0 terminieren
    memset (__rtn_string+len,       0, 1);
}

char* GetValueName(char Content[])
{
    int len = 0;

    for(int n=0; n<=strlen(Content); n++)
    {
            if (Content[n] == '=') {
            len = n;
            break;
            }
    }

    // Speicher auf Heap allozieren !
    char  * __rtn_string = new char[len];

    // kopieren des gewünschten bereichs
    memcpy (__rtn_string, Content, len);
    // mit 0 terminieren
    memset (__rtn_string+len,       0, 1);

    // Rückgabe als Pointer auf Char
    return __rtn_string;

}

int main () {

    // Speicher muss hier alloziert werden
    char txt[200];
    GetValueName ("name=testname",txt);
    printf("GET : %s\n",txt);

    char *string=GetValueName("name=xyz");

    printf("GETSTRING : %s\n",string);

    delete(string);

return 0;
}
Irgentwie fehlt mir Überladung in C richtig :), schöne Sache dies.

mfg. Patrick_C64

Re: String Problem

Verfasst: Sa Okt 22, 2011 3:25 pm
von Kmitska

Code: Alles auswählen

char* GetValueName(char Content[])
{
    int len = 0;

    for(int n=0; n<=strlen(Content); n++)
    {
            if (Content[n] == '=') {
            len = n;
            break;
            }
    }
    char  * __rtn_string = new char[len];
    memcpy (__rtn_string, Content, len);
    memset (__rtn_string+len,       0, 1);
    return __rtn_string;

}
Funktioniert wie ich wollte! :)
Danke an Allen, die mir geholfen haben.