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

ed9*_*do0 0 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
Run Code Online (Sandbox Code Playgroud)

你怎么能读到只有第一列固定宽度的文本文件.将该列中的每一行存储到变量中并将其用作函数的参数.

Jon*_*ler 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);
}
Run Code Online (Sandbox Code Playgroud)

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

[Carlos              ] [Rivera Bernal       ]
[Thomas              ] [James Hanner        ]
[James               ] [Patrick Sullivan    ]
[Brayan              ] [Williams            ]
[Khaterine           ] [Smith               ]
[Ben                 ] [Thompson            ]
Run Code Online (Sandbox Code Playgroud)

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

[Carlos              ] [Rivera Bernal 
Thoma]
[s              James] [Hanner
James        ]
[Patrick Sullivan
Bra] [yan              Wil]
[liams
Khaterine     ] [Smith
Ben           ]
Run Code Online (Sandbox Code Playgroud)

您可以使用给定数据的下一个选择是:

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

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

[Carlos] [Rivera Bernal ]
[Thomas] [James Hanner]
[James] [Patrick Sullivan]
[Brayan] [Williams]
[Khaterine] [Smith]
[Ben] [Thompson]
Run Code Online (Sandbox Code Playgroud)

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

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

产量:

[Carlos              ] [Rivera Bernal ]
[Thomas              ] [James Hanner]
[James               ] [Patrick Sullivan]
[Brayan              ] [Williams]
[Khaterine           ] [Smith]
[Ben                 ] [Thompson]
Run Code Online (Sandbox Code Playgroud)

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

[Carlos] [Rivera Bernal]
[Thomas] [James Hanner]
[James] [Patrick Sullivan]
[Brayan] [Williams]
[Khaterine] [Smith]
[Ben] [Thompson]
Run Code Online (Sandbox Code Playgroud)