在C中的文本文件中只读取固定的列宽

时间:2016-01-13 05:57:39

标签: c variables text-files

假设我有这个文本文件data.txt

|-- 20 characters--||-- 20 characters--|
Carlos              Rivera Bernal 
Thomas              James Hanner
James               Patrick Sullivan
Brayan              Williams
Khaterine           Smith
Ben                 Thompson

如何只读取第一列固定宽度的文本文件。将该列中的每一行存储到变量中并将其用作函数的参数。

1 个答案:

答案 0 :(得分:5)

如果您的线条始终填充到40个字符加上换行符,则可以使用%20c来读取每个20个字符的字段。这将挽救空白和所有;如果你愿意的话,你可以把它们除去。请注意,这不会使字符串终止;你必须这样做。

char first[21];
char last[21];

while (scanf(" %20c %20c", first, last) == 2)
{
    first[20] = last[20] = '\0';
    printf("[%s] [%s]\n", first, last);
}

使用格式正确的数据,会产生:

[Carlos              ] [Rivera Bernal       ]
[Thomas              ] [James Hanner        ]
[James               ] [Patrick Sullivan    ]
[Brayan              ] [Williams            ]
[Khaterine           ] [Smith               ]
[Ben                 ] [Thompson            ]

但是,如果第二个字段未填充到(至少)20个字符,%20c将使用换行符并开始下一行:

[Carlos              ] [Rivera Bernal 
Thoma]
[s              James] [Hanner
James        ]
[Patrick Sullivan
Bra] [yan              Wil]
[liams
Khaterine     ] [Smith
Ben           ]

下一个适用于给定数据的选择是:

while (scanf(" %20[^ ] %20[^\n]", first, last) == 2)
    printf("[%s] [%s]\n", first, last);

在第一个字段中最多可读取20个字符(或第一个空白),然后在第二个字段中最多可读取20个字符(或第一个空格)。在我的数据副本上,产生了:

[Carlos] [Rivera Bernal ]
[Thomas] [James Hanner]
[James] [Patrick Sullivan]
[Brayan] [Williams]
[Khaterine] [Smith]
[Ben] [Thompson]

在卡洛斯的名字后面必须有一个尾随空白而不是其他任何人。您可以结合使用这些技术来读取其中包含空白的“名字”:

while (scanf(" %20c %20[^\n]", first, last) == 2)
{
    first[20] = last[20] = '\0';
    printf("[%s] [%s]\n", first, last);
}

产生:

[Carlos              ] [Rivera Bernal ]
[Thomas              ] [James Hanner]
[James               ] [Patrick Sullivan]
[Brayan              ] [Williams]
[Khaterine           ] [Smith]
[Ben                 ] [Thompson]

您可以编写一个函数来使尾随空白空。例如:

#include <assert.h>
#include <stdio.h>

static void null_trailing_blanks(char *buffer, size_t buflen)
{
    assert(buflen > 0);
    buffer[--buflen] = '\0';
    while (buflen > 0 && buffer[buflen-1] == ' ')
        buffer[--buflen] = '\0';
}

int main(void)
{
    char first[21];
    char last[21];

    while (scanf(" %20c %20c", first, last) == 2)
    {
        null_trailing_blanks(first, sizeof(first));
        null_trailing_blanks(last, sizeof(last));
        printf("[%s] [%s]\n", first, last);
    }

    return 0;
}

在完全填充的数据集上,产生:

[Carlos] [Rivera Bernal]
[Thomas] [James Hanner]
[James] [Patrick Sullivan]
[Brayan] [Williams]
[Khaterine] [Smith]
[Ben] [Thompson]