2 Stimmen

Wie lese und speichere ich String beliebiger Länge mit malloc und realloc in C?

Ich habe eine Struktur

typedef struct store
{
   char name[11];
    int age;
} store;

und eine Hauptfunktion (unten ist ein Teil davon):

int main()
{
    int i=0;
    int inputs;
    char line[100];
    char name[11];
    char command[11];
    store read[3000];

    while(i < 3000 && gets(line) != NULL)  
    {
        int tempage;
        inputs = sscanf(line, "%10s %10s %d", command, name, &tempage);
        if (inputs == 3)
        {
            if (strcmp(command, "register") == 0)
             {
             strncpy(read[i].name, name,10);
             read[i].age = tempage;
             i++;
             ....

Ich muss es so ändern, dass es eine Zeile beliebiger Länge lesen und den Namen aus der Zeile speichern kann, die auch eine Zeichenfolge beliebiger Länge mit malloc und realloc ist.

Wie soll ich das angehen?

2voto

asveikau Punkte 37340

Sie müssen die Zeile in kleineren Schritten lesen und die Größe des Puffers entsprechend anpassen.

Als Beispiel (nicht getestet und nicht besonders elegant, nur ein Beispiel):

char *readline(FILE *f)
{
   char *buf = NULL;
   size_t bufsz = 0, len = 0;
   int keep_going = 1;

   while (keep_going)
   {
      int c = fgetc(f);
      if (c == EOF || c == '\n')
      {
         c = 0;             // we'll add zero terminator
         keep_going = 0;    // and terminate the loop afterwards
      }

      if (bufsz == len)
      {
         // time to resize the buffer.
         //
         void *newbuf = NULL;
         if (!buf)
         {
            bufsz = 512; // some arbitrary starting size.
            newbuf = malloc(bufsz);
         }
         else
         {
            bufsz *= 2; // issue - ideally you'd check for overflow here.
            newbuf = realloc(buf, bufsz);
         }

         if (!newbuf)
         {
            // Allocation failure.  Free old buffer (if any) and bail.
            //
            free(buf);
            buf = NULL;
            break;
         }

         buf = newbuf;
      }

      buf[len++] = c;
   }

   return buf;
}

1voto

P.P Punkte 111806

Ändern Sie den Namen[11] in *Name; Weisen Sie dafür jedes Mal Speicher zu, indem Sie malloc .

Im Übrigen, register ist ein Schlüsselwort in der Sprache C. Sie können es nicht verwenden, wie Sie es getan haben!

0voto

Black-Pixel Punkte 201

Ich glaube, was Sie suchen, ist:

char* name;

name = (char*)malloc(sizeof(char));

0voto

pizza Punkte 6703

Dieser alternative Ansatz ähnelt dem von @asveikau, spart aber die Verwendung von malloc() durch Kopieren auf den Stack.

Bitte verwenden Sie dies nicht für die Beantwortung von Hausaufgaben.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
char * slurponeline(FILE *f, int s) {
 const int size = 4096;
 char buffer[size];
 char * r;
 int c,i=0;
 while( i<size && (c = fgetc(f),c>=0 && c!='\n')) buffer[i++]=c;
 if (0 == s && 0 == i) return 0;
 r = (size==i)? slurponeline(f,s+size):malloc(s+i);
 memcpy(r+s,buffer,i);
 return r;
}
int main(int argc, char ** argv) {
 FILE * f = fopen(argc>1?argv[1]:"a.out","rb");
 char * a,*command,*commandend,*name,*nameend;
 int age;
 while (a = slurponeline(f,0)) {
  char * p = a;
  while (*p && *p == ' ') ++p; // skip blanks.
  command = p;
  while (*p && *p != ' ') ++p; // skip non-blanks.
  commandend = p;
  while (*p && *p == ' ') ++p; // skip blanks.
  name = p;
  while (*p && *p != ' ') ++p; // skip non-blanks.
  nameend = p;
  while (*p && *p == ' ') ++p; // skip blanks.
  age = atoi(p);
  *commandend=0;
  *nameend=0;
  printf("command: %s, name: %s, age: %d\n",command,name,age);
  free(a);
 }
}

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