扫描文件中带有空格的字符串,同时扫描同一行之前和之后的数字

问题描述 投票:0回答:2

我实际上是新手,所以我在学习时遇到了一个错误,实际上我正在尝试从文件fscanf,然后将其显示在屏幕上,一切正常,直到我在文件中添加带空格的书名为止。它显示book.id很好,但仅显示该书的名字,其后的整数变为0。

样本输出:

enter image description here

我的功能:

void display_unsorted(FILE *fptr){
    int x;
    int lines_num=how_many_lines_in_file(fptr);

    fptr=fopen("books.dat","r");
    if(fptr==NULL){
    printf("this file is not open");}

    for(i=0;i<lines_num;i++){
    fscanf(fptr,"%d\t%s\t%d\n",&books[i].id,books[i].name,&books[i].quantity);
    }
    for(x=0;x<lines_num;x++){
    printf("%d\t%s\t%d\n",books[x].id,books[x].name,books[x].quantity);
    }

    fclose(fptr);    
}
c scanf
2个回答
0
投票

关于:

fscanf(fptr,"%d\t%s\t%d\n",&books[i].id,books[i].name,&books[i].quantity);

建议:

fscanf( fptr,"%d %s %d",
             &books[i].id,
              books[i].name,
             &books[i].quantity );

因为格式字符串中的spaces将吸收/舍弃输入中的white space。括号内和逗号后的空格使代码更具可读性

但是,如果书名中包含空格,则最好将整行读入内存缓冲区,然后使用strtok()使用逗号作为分隔符来提取连续的字段,类似于:

int i = 0;
char buffer[1024];
while( i<lines_num && fgets( buffer, sizeof buffer, fptr ) )
{
    char *token = strtok( buffer, ",\t\n" );
    if( token )
    {
        books[i].id = atoi( token );

        token = strtok( NULL, ",\t\n" );
        if( token )
        {
            strcpy( books[i].name, token );

            token = strtok( NULL, ",\t\n" );
            if( token )
            {
                books[i].quantity = atoi( token );
            }
        }
    } 
    i++;
}

注意:strtok()将跳过没有前导数据字符的字符定界符。

注意:如果输入文件中的任何行格式错误,例如没有足够的字段,则此代码可能会失败。


0
投票

[fscanf当找到空白时将停止读取,您可以使用以下方法来覆盖此行为:

fscanf(fptr,"%d %99[^0-9] %d\n", &books[i].id, books[i].name, &books[i].quantity);
                ^^^^^^^^^

翻译,最多读取99个字符的字符串,找到任何数字(即0到9的字符)时将停止读取。

我删除了\t,这是没有必要的,即使文件包含它们,空格也足够。

请注意,这是针对books[i].name容器的,最大大小为100个字符,即99个字符加上空终止符。

还请注意,如果字符串中包含数字,则此功能将无法正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.