繁体   English   中英

读取带有空格的字符串

[英]Reading a string with blank spaces

我正在尝试使用结构读取文件,在我遇到带空格的字符串之前似乎一切都很好,让我举个例子。

在我的文件中,我有这样的文本:

卢卡 21 巴勒莫大学 22.3

我可以阅读所有行,但是当我到达第三个元素即大学时,它只读取“Università”而不是其余的。 我试过使用 [^\t\n] 但它也会读取下一个信息,我不想要这个。 这是代码:

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

typedef struct{
    char nome[30];
    int eta;
    char universita[30];
    double media;
}Studente;

int main(int argc, char** argv){

    FILE* fp;
    Studente s;
    if((fp=fopen("studenti.txt", "r ")) == NULL){
        perror("fopen");
        exit(1);
    }

    char buffer[200];   //tipicamente 200 caratteri stanno su una riga
   // fgets(buffer, 200, fp);  //facciamo una prima lettura
    
    /*while(!feof(fp)){
        sscanf(buffer, " %s %d %s %f", &s.nome, &s.eta, &s.universita, &s.media); //assegnamo il valore della stringa contenuta nel buffer ai tre indirizzi di memoria
        printf("Lo studente si chiama: %s\n", s.nome);
        printf("Ha %d anni\n", s.eta);
        printf("Frequenta %s\n", s.universita);
        printf("Ha una media del %6f\n", s.media);
        fgets(buffer, 200, fp); //continuiamo a leggere
    }*/

    while(fgets(buffer, sizeof(buffer), fp)){
        sscanf(buffer, " %s %d %s %f", s.nome, &s.eta, s.universita, &s.media); //assegnamo il valore della stringa contenuta nel buffer ai tre indirizzi di memoria
        printf("Lo studente chiama: %s\n", s.nome);
        printf("Ha %d anni\n", s.eta);
        printf("Frequenta %s\n", s.universita);
        printf("Ha una media del %lf\n", s.media);
        printf("\n");
    }

    fclose(fp);

    return 0;
}

我想要的输出是:名字是 X 他是 y 他去 z 他的分数是 k

提前致谢。

假设:

  • 学生姓名不包含空格。
  • 大学名称可以包含空格,但不包含数字。
  • 平均值(媒体)不以点开头,例如.12

那你试试:

#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
//#include <ctype.h>
#define FILENAME "studenti.txt"

typedef struct {
    char nome[30];
    int eta;
    char universita[30];
    double media;
} Studente;

/*
 * removes trailing spaces of str by modifying the array str
 */
char *trimright(char *str)
{
    char *p;
    for (p = str; *p != '\0'; p++);
    for (--p; p - str >= 0 && (*p == ' ' || *p == '\t') ; p--) {
        *p = '\0';
    }
    return str;
}

int main(int argc, char **argv)
{
    FILE *fp;
    Studente s;
    char buffer[200];   // tipicamente 200 caratteri stanno su una riga
    int n;              // count the number of elements

    if ((fp = fopen(FILENAME, "r")) == NULL) {
        perror(FILENAME);
        exit(1);
    }

    while (fgets(buffer, sizeof(buffer), fp)) {
        n = sscanf(buffer, "%s %d %[^0-9] %lf", s.nome, &s.eta, s.universita, &s.media);
        if (n == 4) {
            printf("Lo studente chiama: %s\n", s.nome);
            printf("Ha %d anni\n", s.eta);
            printf("Frequenta %s\n", trimright(s.universita));
            printf("Ha una media del %f\n", s.media);
        } else {
            printf("Possible format error with: %s", buffer);
        }
        printf("\n");
    }

    fclose(fp);
    return 0;
}

标识符%[^0-9]使sscanf读取数字以外的字符。 那么解析的字符串s.universita可能包含尾随空格字符。 函数trimright用于修剪它们。 如果您不介意包含尾随空格字符,则无需使用该功能。

如果您想在大学名称中使用数字,请告诉我。

使用strrchr查找记录中的最后一个空格。
从该指针,尝试扫描双精度。
尝试从记录中扫描一个字符串和一个整数。 %u说明符将存储扫描处理的字符数。
减去指针以获得最后一个空格的字符数。
减去处理的字符数,得到剩余子串的字符数。
strncpy子字符串,确保设置零终止符。

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

typedef struct{
    char nome[30];
    int eta;
    char universita[30];
    double media;
}Studente;

int main ( void) {
    char buffer[200] = "Luca 21 Università di Palermo 22.3";
    char *space = NULL;
    int count = 0;
    Studente s = { "", 0, "", 0.0};

    if ( ( space = strrchr ( buffer, ' '))) { // pointer to last space
        if ( 1 == sscanf ( space, "%lf", &s.media)) {
            if ( 2 == sscanf ( buffer, "%29s%d %n", s.nome, &s.eta, &count)) {
                int length = (int)(space - buffer) - count;
                if ( length > 0 && length < sizeof s.universita) {
                    strncpy ( s.universita, buffer + count, length);
                    s.universita[length] = 0;

                    printf ( "%s\n", s.nome);
                    printf ( "%d\n", s.eta);
                    printf ( "%s\n", s.universita);
                    printf ( "%f\n", s.media);
                }
                else {
                    fprintf ( stderr, "Sub-string is too long\n");
                }
            }
            else {
                fprintf ( stderr, "Could not scan string and integer\n");
            }
        }
        else {
            fprintf ( stderr, "Could not scan double\n");
        }
    }
    else {
        fprintf ( stderr, "Could not find a space\n");
    }
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM