c - 奇数 'skip' 函数 : error when running is double loops

标签 c algorithm file file-io io

我的任务是创建一个函数,该函数除了在换行符处跳过一行外什么都不做,而且它还会丢弃超出字符数组容量的一行的其余部分。

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

void skip(FILE *stream)
{
    char line[30];
    //while (fscanf(stream, "%*[^\n]")) {}
    while(fscanf(stream, "%s", line)) {
        if (strlen(line) > 30) {
            printf("invalid, str length: %lu", strlen(line));
            exit(0);
        }
    }
    printf("\n");
}

int main(int argc, char *argv[])
{
    FILE *stream;
    char line[30];
    int count = 0;
    stream = fopen(argv[1], "r");
    while (fscanf(stream, "%s", line) != EOF) {
        fprintf(stdout, "%s", line);
        skip(stream);
        count++;
    }
    printf("%d", count);
    fclose(stream);
    return 0;
}

运行该程序,它有一个命令行参数,它以一个文件作为选项,它指的是输入文件,例如input.txt 像这样:

dog
dog
cow
milk
horse
shoe
rat
moose
milk
boat
goat

我当前的输出是:

dog dog cow milk horse shoe rat moose milk boat goat

我想要每行一个字的版本作为输出,就像输入一样,只要没有行太长。一行版本是错误的输出,也是我最近得到的那种。

我知道这可能是一个典型的问题,我可以在普通程序中用换行符打印它,但在给定情况的情况下,在这个函数中,这是一件很奇怪的事情。

最佳答案

看看 http://en.cppreference.com/w/c/io/fscanf

这只允许读取任意数量的字符:

(optional) integer number (greater than zero) that specifies maximum field width, that is, the maximum number of characters that the function is allowed to consume when doing the conversion specified by the current conversion specification. Note that %s and %[ may lead to buffer overflow if the width is not provided.

然后这允许您读取但不存储一行的其余部分:

(optional) assignment-suppressing character *. If this option is present, the function does not assign the result of the conversion to any receiving argument.

然后这允许您阅读(忽略,见上文)所有内容而不是换行符:

[set] matches a non-empty sequence of character from set of characters. If the first character of the set is ^, then all characters not in the set are matched. If the set begins with ] or ^] then the ] character is also included into the set. It is implementation-defined whether the character - in the non-initial position in the scanset may be indicating a range, as in [0-9]. If width specifier is used, matches only up to width. Always stores a null character in addition to the characters matched (so the argument array must have room for at least width+1 characters)

例如用这个替换你的循环
(注意删除了不需要的 skip()
调用 而且我有意只读了最多四个字符,以演示效果):

while (fscanf(stream, "%4s%*[^\n]", line) != EOF) {
    fprintf(stdout, "%s\n", line);
    count++;
}

确保读取的字符至少比存储结果的数组大小少一个字符,因为我突出显示的部分(粗体)。

输出:

dog
dog
cow
milk
hors
shoe
rat
moos
milk
boat
goat
11

如果您需要使用skip(),您可以将其定义为:

void skip(FILE *stream)
{
    fscanf(stream, "%*[^\n]");
}

然后这样调用:

while (fscanf(stream, "%4s", line) != EOF) {
    fprintf(stdout, "%s\n", line);
    skip(stream);
    count++;
}

关于c - 奇数 'skip' 函数 : error when running is double loops,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46557370/

相关文章:

c++ - C 中的 constexpr(或等价物)

c - 如何从字符串中按数字分隔单词

c - 设置定时器问题

algorithm - 在求职面试中要求解决 NP 完全问题是否正确?

安卓写入文件

c - 链接文件而不是链接列表

c - (char*)malloc(sizeof(char)) 导致段错误,怎么办?

algorithm - 将 HSL 转换为 RGB 时出现问题

multithreading - 关于作者如何在读者/作者算法中被签名

objective-c - 获取 Cocoa 中文件的类型