Tengo un archivo .txt con cadenas en cada línea y un número asignado a cada cadena y un - entre la cadena y el número.

String file

Ahora quiero leer solo la parte de la cadena, no el número o el - intermedio, almacenarlos en una matriz y escribir solo las cadenas en otro archivo.

Usé el siguiente enfoque:

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

#define MAX 100

struct String {
    long long int num;
    char name[50];
    char C;
} S[MAX], temp;

void file_write(int n, struct String S[]) {
    FILE *pp;
    pp = fopen("std3.txt", "a");       //second file where I want to write only string part.
    for (int i = 0; i < n; i++) {
        fprintf(pp, "%s", S[i].name);    //storing the strings in another file
        fputs("\n", pp);
    }
    fclose(pp);
}

int main() {
    int n;
    FILE *fp;
    fp = fopen("str.txt", "r");
    printf("Enter the number of strings : ");
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        fscanf(fp, " %[^\n]", S[i].name);
        fscanf(fp, "%lld", &S[i].num);
        fscanf(fp, "%c", &S[i].C);
    }
    file_write(n, S);
    fclose(fp);
    return 0;
}

Pero obtengo un resultado no deseado:

enter image description here

1
Nova Stark 8 dic. 2020 a las 17:20

2 respuestas

La mejor respuesta

Aquí hay una solución simple que usa fscanf() y la opción de supresión de asignación *:

#include <stdio.h>

int main() {
    int n = 0;
    FILE *fp = fopen("str.txt", "r");
    // second file where I want to write only string part.
    FILE *pp = fopen("std3.txt", "a");
    if (fp == NULL || pp == NULL) {
        fprintf(stderr, "cannot open files\n");
        return 1;
    }
    printf("Enter the number of strings: ");
    scanf("%d", &n);

    for (int i = 0; i < n; i++) {
        char name[50];
        int c;
        if (fscanf(fp, "%*d - %49[^\n]", name) == 1) {
            fprintf(pp, "%s\n", name);
            /* flush any extra characters and the newline if present */
            while ((c = getc(fp)) != EOF && c != '\n')
                continue;
        } else {
            break;
        }
    }
    fclose(fp);
    fclose(pp);
    return 0;
}
1
chqrlie 8 dic. 2020 a las 14:58

Scanf (y sus variaciones) es una función muy poderosa ... Creo que la siguiente línea es lo que quieres.

for(int i=0;i<n;i++)
{
    fscanf(fp, "%*[^A-Z]%[^\n]", S[i].name);
}

Una breve descripción de lo que hace es: descarta cualquier carácter que no sea una letra mayúscula y luego lee todo desde la primera letra mayúscula hasta el final de la línea.

Si los nombres pueden comenzar con minúsculas, puede cambiarlo a:

 fscanf(fp, "%*[^A-Za-z]%[^\n]", S[i].name);
0
vmp 8 dic. 2020 a las 14:59