【问题标题】:C - Working with fopen, fclose, fputc etcC - 使用 fopen、fclose、fputc 等
【发布时间】:2011-12-27 23:53:44
【问题描述】:

我终于让这段代码在我的命令行上使用了一个参数,即它可以使用的一个文件,尽管我设计的代码的概念是它可以使用无限数量的文件。它的作用是获取一些包含由空格分隔的单词的文本文件,并用\n 替换空格,从而创建一个单词列表。虽然,它成功完成了第一个参数,但它只是忽略了第二个。

另一个小问题似乎是它最后还打印了一些垃圾字母,一个 Y 上面有两个点;我假设一些 EOF 符号,但我似乎无法阻止这种情况发生!

int main(int argc, char** argv) {
    FILE *fpIn, *fpOut;
    int i, j;
    j = 1;
    char c;
    char myString[256];

    printf("%d", argc);
    printf("\n");
    printf("The following arguments were passed to main(): ");
                for(i=1; i<argc; i++) printf("%s ", argv[i]);
    printf("\n");

    while(argc--) {
        for(i = 1; i < argc; i++) {
            fpIn = fopen(argv[j], "rb");
            snprintf(myString, 256, "%s~[%d]", argv[j], i);
            fpOut= fopen(myString, "wb");
            while (c != EOF) {
                c = fgetc(fpIn);
                if (isspace(c)) 
                    c = '\n';
                fputc(c, fpOut );
            }
            j++;
        }
    }
    return 0;
}

【问题讨论】:

  • Working with Text Files Two 的可能副本。您对该问题的接受答案解释了为什么您会得到那个额外的垃圾字符。您的代码在此问题中仍然不正确。
  • 是的,这是我以前的帖子,虽然我已经取得了一些进展,但通常不会在旧帖子上得到回复,所以我想我可以再发一个:)
  • 我真的不明白为什么,如果我说实话
  • 简而言之,考虑以下规则:永远不要将EOF 值写入文件。 现在,您的代码中会如何发生这种情况? (确实如此,你必须弄清楚如何解决它。)
  • 我似乎仍然无法让它适用于多个参数:/

标签: c file-io io fopen fclose


【解决方案1】:

getchar()getc()fgetc() 函数(或宏)返回 int,而不是 char

你必须使用:

int c;

while ((c = fgetc(fpIn)) != EOF)
{
    if (isspace(c))
        c = '\n';
    fputc(c, fpOut);
}

想一想;函数必须能够返回任何有效的char EOF(与任何有效的char 值不同。因此,根据定义,返回值不能是char。 ..

如果你使用char会发生什么?

  • 您的原始代码在测试之前没有初始化 c(因此循环可能会提前中断)。
  • 您的代码在读取 EOF 后没有立即测试 c(因此它可能会打印一个垃圾字符,通常是 ÿ、带分音符号的拉丁小写字母 Y、U+00FF)。
  • 如果您的 char 类型是无符号的,您将永远不会看到 EOF。
  • 如果您的 char 类型已签名,则某些有效字符(通常又是 ÿ)将被误解为 EOF。

我似乎仍然无法让它适用于多个参数。

问题是你运行的双循环:

int i, j;
j = 1;

while (argc--)
{
    for (i = 1; i < argc; i++)
    {
        fpIn = fopen(argv[j], "rb");
        ...process fpIn...
        j++;
    }
}

假设您使用两个文件名调用命令;然后argc == 3

第一次通过while 循环后,argc == 2。然后,您执行for 循环,i 取值 1;你打开argv[1](因为j == 1)。您处理该文件;然后将 j 增加到 2,然后将 i 增加到 2。第二次围绕 for 循环,i == 2,argc 也是如此,因此 for 循环终止。 while 循环将 argc 再次递减为 1,但测试 2 != 0。但是,for 循环设置了i = 1,然后因为i == argc 而终止。 while 循环将 argc 减为 1,然后重复。

您可以使用while 循环或for 循环,但您不需要同时使用两者。

所以,要么:

for (i = i; i < argc; i++)
{
    ...process argv[i]...
}

或者:

while (--argc > 0)
{
    ...process *++argv...
}

我会使用for 循环。

【讨论】:

  • 谢谢,我在当前循环中添加了一个检查,看看它是否是 EOF,如果 ( c == EOF) {break;} 修复了它!
  • 我似乎仍然无法让它适用于多个参数:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多