2017-11-06 4 views
0

Ich schreibe ein Programm, das nach einem Namen in einer CSV-Datei suchen und den Datensatz (alle Informationen in der gleichen Zeile wie der Name) kopieren soll es.Kopieren einer Zeile aus einer CSV-Datei mithilfe von Zeigern

Zum Beispiel, wenn CSV-Datei enthält:

Bob, 13, 12345612 
Eli, 12, 21398743 

Ich würde Eingang "Bob" die erste Zeile zu bekommen, und kopieren Sie diese in ein Array "record" genannt.

Bisher mein Code wie folgt:

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

void FindRecord(char *a, char *b, char c[]); 

void main(void){ 

    char arrayName[100]; 
    char arrayNewname[100]; 
    char *name = arrayName; 
    char *newname = arrayNewname; 
    char record[1000]; 

    printf("Please input a name in the phonebook: "); 
    scanf("%s", name); 

    printf("Please input a replacement name: "); 
    scanf("%s", newname); 

    FindRecord("phonebook.csv",name,record); 
    } 

    void FindRecord(char *filename, char *name, char record[]){ 

    //Create temp array of max size 
    char temp[1000]; 

    //Open file 
    FILE *f = fopen(filename, "r"); 
    //Make sure file exists 
    if (f == NULL){ 
     printf("File does not exist"); 
     fclose(f); 
     exit(1); 
    } 

    //While 
    while(!feof(f)){ 
     //Read one line at a time 
     fgets(temp, 1000, f); 
     int i = 0; 
     int *p; 
     for(int i = 0; i < 1000; i++){ 
      if(temp[i] == *name){ 
       record[i] = temp[i]; 
       name++; 
      } 
      size_t n = (sizeof record /sizeof record[0]); 
      if(temp[i] == *name){ 
      *p = temp[i + n]; 
      } 
     } 
    } 
    printf("%s", record); 
    fclose(f); 
} 

Im Grunde habe ich Bob gefunden und Bob kopiert, aber nicht verstehen, wie man Zeiger gehen (nicht verwenden string.h erlaubt) und Kopieren der Rest der Linie. Ich habe versucht, mit der Länge des Wortes herumzuspielen, sobald ich es gefunden habe, aber das funktioniert nicht wegen der Zeiger. Jede Hilfe/Hinweise wären willkommen.

+1

[Warum ist „während (! Feof (Datei))“ immer falsch?] (Https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) –

+1

Siehe auch [Was soll 'main()' in C und C++ zurückgeben?] (Https://stackoverflow.com/questions/204476/) –

+1

Um Strings zu vergleichen, benutzen Sie 'strcmp' oder' strstr' etc. –

Antwort

0

Wenn Sie nicht string.h verwenden dürfen, müssen Sie Zeichenfolgen durch Zeichen vergleichen. Beginnen Sie mit einer Schleife, um den Namen zu finden.

See: Compare two strings character by character in C

und kopieren Sie dann den Rest des Datensatzes. Entweder char von char oder mit fortgeschritteneren Funktionen wie memcpy: https://www.techonthenet.com/c_language/standard_library_functions/string_h/memcpy.php

Nun, wer ist int *p?

Sie haben diesen Zeiger nicht initialisiert. Sie müssen es entweder malloc oder einem vorhandenen Speicher zuweisen. Weitere Informationen:

Ich denke, Sie sollten mehr über Zeiger lesen und dann wird die Dinge viel besser für Sie arbeiten.

0

string.h nicht zu verwenden ist eine gute Übung in der Berechnung der String-Längen manuell (notwendig, um die hinteren '\n' aus den Zeilen mit fgets zu lesen) und auch eine gute Übung für manuelle String-Vergleiche.

Wenn Sie beispielsweise Zeilen in buf lesen, können Sie eine einfache for-Schleife verwenden, um die Länge von buf, z.

int blen = 0; 
    for (; buf[blen]; blen++) {}  /* get line length */ 

(Anmerkung: Sie finden die Länge name, sagen nlen in ähnlicher Weise)

mit Dann ist die Länge in blen, können Sie leicht prüfen, ob das letzte Zeichen in buf ist die '\n' Zeichen und entfernen Sie es durch Überschreiben der Newline mit dem Null-Terminierung Zeichen, z

if (blen && buf[blen - 1] == '\n') /* check/remove '\n' */ 
     buf[--blen] = 0;    /* overwrite with '\0' */ 

Der Rest Ihrer findrecord Funktion ist nur eine Frage der für den Charakter freuen uns über jedes Zeichen laufen, die das erste Zeichen in name ist.Einmal gefunden, vergleichen Sie einfach dann weiter nlen Zeichen, um zu sehen, ob Sie name in buf gefunden haben. Sie können ganz einfach tun, mit:

  char *np = name,   /* pointer to name */ 
       *bp = p;    /* current pointer in buf */ 
      ... 
      for (i = 0;  /* compre name in buf */ 
       i < nlen && *np && *bp && *np == *bp; 
       i++, np++, bp++) {} 
      /* validate nlen chars match in buf */ 
      if (np - name == nlen && *(np-1) == *(bp-1)) { 

One Sie validiert haben Sie name in buf gefunden, einfach kopieren buf zu record Ihre nul-beenden Versicherungrecord wenn buf getan Kopieren, z.B.

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

enum { MAXC = 100, MAXL = 1000 }; /* if you need constants, define them */ 

char *findrecord (FILE *fp, char *name, char *record); 

/* main is type 'int', and has arguments -- use them */ 
int main (int argc, char **argv) { 

    char name[MAXC] = "", 
     replace[MAXC] = "", 
     record[MAXL] = "", 
     *matched; 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : NULL; 

    if (!fp) { /* validate file open for reading */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 
    /* prompt, read, validate name */ 
    printf ("Please input a name in the phonebook: "); 
    if (scanf ("%99[^\n]%*c", name) != 1) { 
     fprintf (stderr, "error: invalid input - name.\n"); 
     return 1; 
    } 
    /* prompt, read, validate replace */ 
    printf("Please input a replacement name: "); 
    if (scanf ("%99[^\n]%*c", replace) != 1) { 
     fprintf (stderr, "error: invalid input - replace.\n"); 
     return 1; 
    } 
    /* search name, copy record, return indicates success/failure */ 
    matched = findrecord (fp, name, record); 
    if (fp != stdin) fclose (fp); /* close file if not stdin */ 

    if (matched) { /* if name matched */ 
     printf ("record : '%s'\n", record); 
    } 

    return 0; /* main() returns a value */ 
} 

char *findrecord (FILE *fp, char *name, char *record){ 

    char buf[MAXL] = "";    /* buf for line */ 

    while (fgets (buf, MAXL, fp)) {  /* for each line */ 
     char *p = buf; 
     int blen = 0; 
     for (; buf[blen]; blen++) {}  /* get line length */ 
     if (blen && buf[blen - 1] == '\n') /* check/remove '\n' */ 
      buf[--blen] = 0;    /* overwrite with '\0' */ 
     for (; *p && *p != '\n'; p++)  /* for each char in line */ 
      if (*p == *name) {    /* match start of name? */ 
       char *np = name,   /* pointer to name */ 
        *bp = p;    /* current pointer in buf */ 
       int i = 0,     /* general 'i' var */ 
        nlen = 0;    /* name length var */ 
       for (nlen = 0; name[nlen]; nlen++) {} /* name length */ 
       for (i = 0;  /* compre name in buf */ 
        i < nlen && *np && *bp && *np == *bp; 
        i++, np++, bp++) {} 
       /* validate nlen chars match in buf */ 
       if (np - name == nlen && *(np-1) == *(bp-1)) { 
        bp = buf; 
        for (i = 0; buf[i]; i++) /* copy buf to record */ 
         record[i] = buf[i]; 
        record[i] = buf[i];   /* nul-terminate */ 
        return record;    /* return record */ 
       } 
      } 
    } 

    return NULL; /* indicate no match in file */ 
} 

Beispiel Verwendung/Output

$ ./bin/findrec dat/bob.csv 
Please input a name in the phonebook: Bob 
Please input a replacement name: Sam 
record : 'Bob, 13, 12345612' 

Nicht Spiel Beispiel

$ ./bin/findrec dat/bob.csv 
Please input a name in the phonebook: Jerry 
Please input a replacement name: Bob 
:

  if (np - name == nlen && *(np-1) == *(bp-1)) { 
       bp = buf; 
       for (i = 0; buf[i]; i++) /* copy buf to record */ 
        record[i] = buf[i]; 
       record[i] = buf[i];   /* nul-terminate */ 
       return record;    /* return record */ 
      } 

es insgesamt Einlochen, könnten Sie etwas Ähnliches wie die folgenden tun

Schauen Sie die Dinge über und lassen Sie mich wissen, wenn Sie weitere Fragen haben.

Verwandte Themen