[C] mehrere ints in string schreiben

Hallo,
also ich bin im Programmieren noch ein blutiger Anfänger und würde gerne wissen wie ich folgendes Problem lösen kann:

Also ich lese einen Satz Zeichen für Zeichen ein, welcher in einen String gespeichert wird... Die Zeichen in dem String sollen dan in ASCII-Code umgewandelt werden und dieser Code wiederum als Zeichen in einem weiteren String gespeichert werden:

Beispiel:

Eingabe: GO
Inhalt des 1. Strings: GO
Inhalt des 2. Strings nach Umwandlung: 7179 (71=G, 79=O)

Ich hab mir zuerst gedacht, dass ich den String Zeichen für Zeichen einlese und das Zeichen gleich mit

sprintf(string2, "%i", zeichen);

mache, aber da wird ja jedesmal danach ein '\0' angehängt...
wie kann ich das jetzt lösen?

mfg
marco
 
Code:
const char *x = "90";
  for(size_t i=0; i < strlen(x); ++i) {
      printf("%c = %x\n",x[i],x[i]);
      }
 
Wenn str, der eingelesene String ist, dann würde ich folgendermaßen vorgehen:
Code:
char *str2 = malloc(strlen(str)*3 + 1);
memset(str2,0,strlen(str)*3+1);
int i;
for(i=0;i<strlen(str);i++) {
    sprintf(str2,"%s%i",str2,str[i]&0xff);
}
Zuerst legt man ein hinreichend großes Array an(doppelt so groß wie der Ausgangsstring + Null-Byte) und danach wandelt man schrittweise die einzelnen Zeichen der Eingabe in die dezimale Darstellung ihres Ascii-Codes um. Die Verknüpfung mit 0xff braucht man, wenn in der Eingabe Zeichen >0x7f vorkommen, da es sonst wegen der Darstellung von negativen Zahlen Probleme geben kann(siehe Zweierkomplement). Allerdings hat man mit dieser Variante ein paar Bytes verschwendet, da die dezimale Darstellung meistens nur zweistellig ist, aber das dürfte in den meisten Fällen vernachlässigbar sein. Ansonsten müsste man den Eingabestring Schritt für Schritt durchgehen und jedes Mal die benötigte Zeichenanzahl bestimmen(str >= 100 überprüfen), was ich hier aber mal zwecks Anschaulichkeit sein gelassen habe.
Man könnte das ganze natürlich auch während dem Einlesen erledigen und mit realloc arbeiten, aber diese Variante halte ich für lesbarer.

Wenn du das ganze nur ausgeben willst und nicht in einem String haben möchtest, ist natürlich Kecis Variante geeigneter.
 
Original von Keci
const char *x = "90";
for(size_t i=0; i < strlen(x); ++i) {
printf("%c = %x\n",x,x);
}


Ich verstehe jetzt nicht ganz was das mit meinem Problem zu tun hat?
Du gibst 9 und 0 jeweils als zeichen und als hex-Zahl aus? (soweit ich das mit meinen grundkenntnissen erkennen kann xD)


Original von Lesco
Wenn str, der eingelesene String ist, dann würde ich folgendermaßen vorgehen:
Code:
char *str2 = malloc(strlen(str)*3 + 1);
memset(str2,0,strlen(str)*3+1);
int i;
for(i=0;i<strlen(str);i++) {
    sprintf(str2,"%s%i",str2,str[i]&0xff);
}

Danke für die Antwort.
Leider verstehe ich nur einen Teil deines Codes^^... also du legst ein dreimal so großes Array (+1) an, wie das Ausgangsarray.
Und die Memset-Funktion füllt doch den ganzen String mit Nullen oder? (wenn ja für was?)
Den Rest versteh ich jetzt auch fast... Ist das nicht so, dass nach jedem sprintf() wieder eine binäre Null angehängt wird?
Dann würden ja im str2-String ein paar binäre Nullen herumwandern oder?
Und für was genau ist der &0xff Zusatz? Könntest du mir das vielleicht genauer erklären?
 
Code:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(void) {

    char *string = "Hallo, ich bin ein String !\nblub";
    int strlaen  = strlen(string);
    int i;

    /* 3 mal die Laenge (in Bytes) reservieren, da jedes Char einen 3-stelligen Int-Wert haben kann. */
    char *str_um = (char *) malloc( strlaen*3 );

    /* Sprintf-Wert wird in 4-Byte-Buffer gespeichert, da 3-stelliger Int-Wert + '\0'. */
    char buff[4];

    printf("Stringlänge: %d\n", strlaen);

    for( i = 0; i < strlaen; ++i ) {

        sprintf(buff, "%d", (int) string[i]);

        /* Nun wird der (von sprintf in buff) ausgelesene Int-Wert (evtl. dreistellig, z.Bsp. z = 122 )
           an den Ausgabe-string gehaengt, die von buff[3] '\0' wird bis zum Ende ueberschrieben.*/
        strcat(str_um, buff);
        printf("%d", (int) string[i]);
    }

    printf("\n%s (string)\n", str_um);

    return EXIT_SUCCESS;
}
Evtl. 7. und 8. Zeile mit unten stehenden Code austauschen, da strlen bis '\0' zaehlt etc.

Code:
    char string[] = "Hallo, ich bin ein String !\nblub";
    int strlaen   = sizeof(string)/sizeof(char)-1;
 
Original von marcotesoalli

Danke für die Antwort.
Leider verstehe ich nur einen Teil deines Codes^^... also du legst ein dreimal so großes Array (+1) an, wie das Ausgangsarray.
Und die Memset-Funktion füllt doch den ganzen String mit Nullen oder? (wenn ja für was?)
Den Rest versteh ich jetzt auch fast... Ist das nicht so, dass nach jedem sprintf() wieder eine binäre Null angehängt wird?
Dann würden ja im str2-String ein paar binäre Nullen herumwandern oder?
Und für was genau ist der &0xff Zusatz? Könntest du mir das vielleicht genauer erklären?

Die memset-Funktion nutze ich, damit ich es mir sparen kann vorher und nachher mich jeweils um die Nullbytes zu kümmern. Durch das sprintf("%s%i" wird zuerst wieder der bisherige String in den Buffer geschrieben, dann die Zahl angehängt und das Endergebnis bekommt dann eine Null angehängt, was aber nicht weiter schlimm ist, da das Ergebnis im nächsten Durchlauf ohnehin wieder neu von sprintf verwendet wird. Im Grunde die selbe Methode wie von Gentfloo, lediglich ohne den temporären Buffer für das aktuelle Zeichen.

Zu der Sache mit dem &0xFF. Intern sind vorzeichenbehaftete Zahlen durch das Zweierkomplement dargestellt, d.h. das MSB(most significant bit, also "ganz links" bei konventioneller Darstellung) ist bei negativen Zahlen 1. Wegen der impliziten Konvertierung der Zeichen in ints, kann es nun vorkommen, dass z.B. aus einem Zeichen mit dem Ascii-Code 0x80 eine negative Zahl wird, da das höchste Bit gesetzt ist und bei der Konvertierung versucht wird, dass Vorzeichen mit in den größeren Zahlenbereich zu übernehmen.
Um das zu verhindern, setzt man nach der Umwandlung durch &0xFF alle Bits außer den niedrigsten 8 auf 0.
Hier ein Beispiel:
Code:
char x = 0x81;
printf("%i",x);
Dies würde daher -127 ausgeben, obwohl 129 gemeint ist.
 
Original von Keci
@Lesco

nunja.. in C/C++ kann man es angeben :D

unsigned und signed ;)

Ja schon, aber es wird doch kaum verwendet, oder wie oft siehst du unsigned char* foo statt bloß char* foo, da es in dem Großteil der Fälle eben keine Probleme bereitet? ;)
 
Zurück
Oben