Si vous ne comptez pas utiliser fgets()
(peut-être parce que vous voulez supprimer le saut de ligne, ou vous voulez traiter avec "\r"
, "\n"
ou "\r\n"
fins de ligne, ou si vous voulez savoir combien de caractères ont été lus), vous pouvez utiliser en fonction de squelette:
int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && c != '\n' && dst < end)
*dst++ = c;
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}
Il reconnaît que la nouvelle ligne comme fin de ligne; il laisse tomber la nouvelle ligne. Il ne déborde pas le tampon; il ne rejette pas les caractères en excès, donc s'il est appelé à lire une très longue ligne, il lira la ligne en morceaux; il renvoie le nombre de caractères lus.Si vous avez besoin de faire la distinction entre les trop-plein et une ligne qui se trouve être la longueur de la mémoire tampon - 1, alors vous avez probablement besoin de préserver la nouvelle ligne - avec des changements consécutifs dans le code:
int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && dst < end)
{
if ((*dst++ = c) == '\n')
break;
}
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}
Il existe d'innombrables variantes mineures sur ce point, par exemple en supprimant les caractères en excès si la ligne doit être tronquée. Si vous voulez gérer DOS, (anciens) de fin de ligne Mac ou Unix, puis emprunter une feuille sur le code CSV à partir "The Practice of Programming" par Kernighan & Pike (un excellent livre) et de l'utilisation:
static int endofline(FILE *ifp, int c)
{
int eol = (c == '\r' || c == '\n');
if (c == '\r')
{
c = getc(ifp);
if (c != '\n' && c != EOF)
ungetc(c, ifp);
}
return(eol);
}
vous pouvez utiliser qui en place du test c != '\n'
:
int get_line(FILE *fp, char *buffer, size_t buflen)
{
char *end = buffer + buflen - 1; /* Allow space for null terminator */
char *dst = buffer;
int c;
while ((c = getc(fp)) != EOF && !endofline(fp, c) && dst < end)
*dst++ = c;
*dst = '\0';
return((c == EOF && dst == buffer) ? EOF : dst - buffer);
}
l'autre alternative de traiter l'ensemble du processus est d'utiliser fread()
et fwrite()
:
void copy_file(FILE *in, FILE *out)
{
char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), in)) != 0)
{
if (fwrite(buffer, sizeof(char), nbytes, out) != nbytes)
err_error("Failed to write %zu bytes\n", nbytes);
}
}
Dans ce contexte, vous souhaitez ouvrir le fichier et de vérifier la validité en, puis appelez:
copy_file(fp, stdout);
Il est 'ch = fgetc (fp)'; pas 'ch = fgetc()'. En plus de ça ... une raison pour laquelle vous ne pouvez pas utiliser 'fgets()'? – ThiefMaster
également, vous obtiendrez une erreur de segmentation ici: buffer [num_chars ++] = ch; si une ligne du fichier dépasse 80 caractères. –
while (! Feof (fp)) {, pas nécessaire n'est-ce pas? – Nyan