427 Stimmen

Wie verkette ich const/literal strings in C?

Ich arbeite in C und muss ein paar Dinge verketten.

Im Moment habe ich das hier:

message = strcat("TEXT ", var);

message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));

Wenn Sie Erfahrung mit C haben, ist Ihnen sicher klar, dass dies zu einem Segmentierungsfehler führt, wenn Sie versuchen, es auszuführen. Wie kann ich das also umgehen?

3voto

Pieter Punkte 16973

Das erste Argument von strcat() muss genügend Platz für die verkettete Zeichenkette bieten. Weisen Sie also einen Puffer mit genügend Platz zu, um das Ergebnis aufzunehmen.

char bigEnough[64] = "";

strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);

/* and so on */

strcat() verkettet das zweite Argument mit dem ersten Argument und speichert das Ergebnis im ersten Argument. Das zurückgegebene char* ist einfach das erste Argument und dient nur Ihrer Bequemlichkeit.

Sie erhalten keine neu zugewiesene Zeichenfolge mit dem ersten und zweiten Argument verkettet, die ich würde vermuten, Sie basierend auf Ihrem Code erwartet.

2voto

Todd Punkte 2263

Sie versuchen, eine Zeichenkette in eine Adresse zu kopieren, die statisch zugewiesen ist. Sie müssen in einen Puffer kopieren.

Konkret:

...snip...

Zielort

Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.

...snip...

http://www.cplusplus.com/reference/clibrary/cstring/strcat.html

Auch hier gibt es ein Beispiel.

2voto

Donald Duck Punkte 7498

Sie können Ihre eigene Funktion schreiben, die das Gleiche tut wie strcat() aber das ändert nichts:

#define MAX_STRING_LENGTH 1000
char *strcat_const(const char *str1,const char *str2){
    static char buffer[MAX_STRING_LENGTH];
    strncpy(buffer,str1,MAX_STRING_LENGTH);
    if(strlen(str1) < MAX_STRING_LENGTH){
        strncat(buffer,str2,MAX_STRING_LENGTH - strlen(buffer));
    }
    buffer[MAX_STRING_LENGTH - 1] = '\0';
    return buffer;
}

int main(int argc,char *argv[]){
    printf("%s",strcat_const("Hello ","world"));    //Prints "Hello world"
    return 0;
}

Wenn beide Zeichenfolgen zusammen mehr als 1000 Zeichen lang sind, wird die Zeichenfolge bei 1000 Zeichen abgeschnitten. Sie können den Wert von MAX_STRING_LENGTH auf Ihre Bedürfnisse zugeschnitten.

1voto

jksante Punkte 29

Versuchen Sie etwas Ähnliches wie dies:

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

int main(int argc, const char * argv[])
{
  // Insert code here...
  char firstname[100], secondname[100];
  printf("Enter First Name: ");
  fgets(firstname, 100, stdin);
  printf("Enter Second Name: ");
  fgets(secondname,100,stdin);
  firstname[strlen(firstname)-1]= '\0';
  printf("fullname is %s %s", firstname, secondname);

  return 0;
}

1voto

technosaurus Punkte 7371

Angenommen, Sie haben ein char[fixed_size] anstelle eines char*, können Sie ein einziges, kreatives Makro verwenden, um alles auf einmal mit einem <<cout<<like Bestellung ("lieber %s die unzusammenhängende %s \n ", "als", "printf style format"). Wenn Sie mit eingebetteten Systemen arbeiten, können Sie mit dieser Methode auch auf malloc und die großen *printf Familie von Funktionen wie snprintf() (Dies verhindert, dass dietlibc sich auch über *printf beschwert)

#include <unistd.h> //for the write example
//note: you should check if offset==sizeof(buf) after use
#define strcpyALL(buf, offset, ...) do{ \
    char *bp=(char*)(buf+offset); /*so we can add to the end of a string*/ \
    const char *s, \
    *a[] = { __VA_ARGS__,NULL}, \
    **ss=a; \
    while((s=*ss++)) \
         while((*s)&&(++offset<(int)sizeof(buf))) \
            *bp++=*s++; \
    if (offset!=sizeof(buf))*bp=0; \
}while(0)

char buf[256];
int len=0;

strcpyALL(buf,len,
    "The config file is in:\n\t",getenv("HOME"),"/.config/",argv[0],"/config.rc\n"
);
if (len<sizeof(buf))
    write(1,buf,len); //outputs our message to stdout
else
    write(2,"error\n",6);

//but we can keep adding on because we kept track of the length
//this allows printf-like buffering to minimize number of syscalls to write
//set len back to 0 if you don't want this behavior
strcpyALL(buf,len,"Thanks for using ",argv[0],"!\n");
if (len<sizeof(buf))
    write(1,buf,len); //outputs both messages
else
    write(2,"error\n",6);
  • Anmerkung 1: Normalerweise würde man argv[0] nicht so verwenden - dies ist nur ein Beispiel
  • Anmerkung 2: Sie können jede Funktion verwenden, die ein char* ausgibt, einschließlich nicht standardisierter Funktionen wie itoa() zur Umwandlung von Ganzzahlen in Zeichenketten.
  • Anmerkung 3: Wenn Sie bereits printf irgendwo in Ihrem Programm verwenden, gibt es keinen Grund, snprintf() nicht zu verwenden, da der kompilierte Code größer (aber inlined und wesentlich schneller) wäre.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X