2009-11-14 11 views
2

En ce moment, j'utilise:Comment récupérer des données et non des lignes entières dans C?

char record[BUFLEN]; 
    if(fgets(record, BUFLEN, fp) != NULL) { 

     /* some code */ 

    } 

pour obtenir des lignes de l'entrée comme:

city=Boston;name=Bob;age=35 
city=New York;name=Michael;age=29 

Puis-je utiliser quelque chose d'autre en C qui me donnerait des lignes non entières jusqu'à ce que « \ n » mais paires séparées comme: "city = Boston" puis "name = Bob", etc?

Répondre

1

Vérifiez la fonction strtok(). Les appels successifs récupéreront chaque jeton de la chaîne.

En utilisant votre exemple:

char record[BUFLEN]; 
if(fgets(record, BUFLEN, fp) != NULL) { 
    char *token; 

    token = strtok(record, ";"); 
    while (token != NULL) 
    { 
      doSomethingWith(token); 
      token = strtok(NULL, ";"); 
    } 
} 
+0

vous auriez encore à lire la ligne complète tokenizer il. ça sonne un peu comme si le PO ne voulait pas lire une ligne de texte complète en premier lieu. – dice

+0

Je luttais avec ça. Puisque vous avez fourni une réponse qui répond à ce critère, notre OP a deux points de vue différents à prendre en compte, selon l'importance d'éviter la mise en cache de la ligne entière. –

2

vous pourriez lire un octet à la fois en utilisant fgetc.

lire jusqu'à = dans un tableau puis jusqu'à; dans un autre

 do { 
      c = fgetc (pFile); 

      if (c == ';') 
      // etc 

     } while (c != EOF); 
+0

Après une considération supplémentaire, j'aime mieux ta réponse que la mienne. Je laisse le mien en place comme alternative. –

0

Vous pourriez dupliquer les fonctionnalités de fgets(), ne l'avoir « fget » par un délimiteur que vous spécifiez, plutôt que \ n. Code ressemblerait à quelque chose comme (c'est PSEUDOCODE):

Dans cette fonction, "DELIM" est le délimiteur que vous souhaitez utiliser. plutôt que \n, il pourrait être ;.

char *GOEfgets(char *buf, int BUFLEN, FILE *fp, char DELIM) 
{ 
    int i = 0; /* counter */ 
    int character; 

    while(character = fgetc(fp)) /* we get a char from the stream one at a time */ 
    { 
     buf[i] = (char)character; /* store that character in the stream */ 

     if ((char)character == DELIM) /* if we run into our delimiter, we stop */ 
     { 
     return buf; 
     } 
    } 

} 
3

Cela ressemble à l'une de ces occasions relativement rares où scanf() peut être utilisé.

Vous pouvez essayer:

while (fscanf(fp, "%[^=]=%[^;]", name, value) == 2) 
{ 
    if ((c = fgetc(fp)) == EOF) 
     break; 
    else if (c == ';') 
     ...continue with same line... 
    else if (c == '\n') 
     ...wrap up current line... 
    else 
     ...congratulations - format error of some sort... 
} 

Vous pouvez également continuer à utiliser 'fgets()' mais utiliser 'sscanf()' dans une boucle similaire à cela.

travail Code de démonstration:

#include <stdio.h> 
int main(void) 
{ 
    char name[20]; 
    char value[20]; 

    while (fscanf(stdin, "%19[^=]=%19[^;]", name, value) == 2) 
    { 
     int c; 
     if ((c = fgetc(stdin)) == EOF) 
      break; 
     else if (c == ';') 
      printf("name = %s; value = %s\n", name, value); 
     else if (c == '\n') 
      printf("name = %s; value = %s\n", name, value); 
     else 
      fprintf(stderr, "Ooops!\n"); 
    } 
    return(0); 
} 
+0

Un bon code, 'scanf' est aussi le bon outil IMO. Pourquoi quelqu'un pourrait-il implémenter l'analyse manuelle pour un cas si simple :) – AraK

+0

+1 vous m'avez montré à quel point mon C est rouillé. – dice