使用C有选择地读取文件的字符串部分

Selectively reading string part of a file using C

我有一个 .txt 文件,每行都有字符串,每个字符串都分配了一个数字,字符串和数字之间有一个 -

现在我只想读取字符串部分而不是数字或中间的 -,将它们存储在一个数组中并只将字符串写入另一个文件。

我使用了以下方法:

#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;
}

但我得到了不希望的输出:

Scanf(及其变体)是一个非常强大的函数...我想下面这行就是您想要的。

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

对其作用的简要描述是:它丢弃任何不是大写字母的字符,然后读取从第一个大写字母到行尾的所有内容。

如果名字允许小写开头,可以改成:

 fscanf(fp, "%*[^A-Za-z]%[^\n]", S[i].name);

这是一个使用 fscanf()* 分配抑制选项的简单解决方案:

#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;
}