【问题标题】:Trying to fprintf a certain string from a file read试图从读取的文件中 fprintf 某个字符串
【发布时间】:2019-08-27 15:30:46
【问题描述】:

我正在努力将一个字符串从一个文件打印到一个新文件,并且似乎无法绕开它也无法让它工作,任何帮助都会很棒。

文件如下所示:

纽约,4:20,3:03 堪萨斯城,12:03,3:00 北湾,16:00,0:20 卡普斯卡辛,10:00,4:02 雷湾,0:32,0:31

我正在尝试将 fprintf 只是文件名添加到一个名为 theCities.txt 的新文件中。这个逻辑在我的脑海中是有道理的,但在实现方面,我不知道如何fprintf 指向字符串的指针。任何帮助都会很棒。

while (fgets(flightInfo[i], 1024, fp) > 0) {
    clearTrailingCarraigeReturn(flightInfo[i]);
    // display the line we got from the fill
    printf("  >>> read record [%s]\n", flightInfo[i]);

    char *p = flightInfo[i];
    for (;;) {
        p = strchr(p, ',');
        fp = fopen("theCities.txt", "w+");
        fprintf(fp, "%s\n", p);
        if (!p)
            break;
        ++p;
    }
    i++;
}

【问题讨论】:

  • while (fgets(flightInfo[i], 1024, fp) > 0) 内的 fp = fopen("theCities.txt", "w+"); 很奇怪。发布minimal reproducible example
  • 为什么在循环中每次都打开该文件?而且你永远不会关闭它。
  • 然后您重新使用用于输入输出的 fp。很多事情都可能(并且将会)出错。

标签: c input printf output


【解决方案1】:

您正在处理错误的文件指针:

FILE *fpIn, *fpOut;
if (!(fpIn= fopen("yourfile.txt", "r"))) return -1;
if (!(fpOut=fopen("cities.txt", "w"))){fclose(fpIn); return -1;}
while (fgets(flightInfo[i], 1024, fpIn) > 0)
{
    clearTrailingCarraigeReturn(flightInfo[i]);
    // display the line we got from the fill
    printf("  >>> read record [%s]\n", flightInfo[i]);

    char *p = flightInfo[i];
    for (;;)
    {
        p = strchr(p, ',');
        fprintf(fpOut, "%s\n", p);
        if (!p) break;
        ++p;
    }

    i++;

}
fclose(fpIn);
fclose(fpOut);

【讨论】:

  • 这确实可以正确打印所有内容,如果我想打印 ',' 之前的内容怎么办?
  • 这不会太难所以我把它留给你。
  • 如果我的回答有帮助,请点击它左边的大数字。
  • 有没有办法在我的打印中跳过(null)?
  • 是的,将if(!p) break; 移到打印之前,但您已经知道了。还没点击左边那个大数字?
【解决方案2】:

你的代码有问题:

  • 您在嵌套范围内重新定义变量fp,这非常令人困惑。
  • 您应该在循环之前只打开一次输出文件。
  • 您应该使用"%.*s" 来输出字符串的一部分而不是行尾。

这是修改后的版本:

FILE *outp = fopen("theCities.txt", "w");
for (i = 0; fgets(flightInfo[i], 1024, fp) > 0; i++) {
    clearTrailingCarraigeReturn(flightInfo[i]);
    // display the line we got from the fill
    printf("  >>> read record [%s]\n", flightInfo[i]);

    int city_length = strcspn(flightInfo[i], ",");
    if (city_length) {
        fprintf(outp, "%.*s\n", city_length, flightInfo[i]);
    }
}
fclose(outp);

【讨论】:

    【解决方案3】:

    只是为了更新我所做的,我使用了@Paul Ogilvie 的方法并对其进行了调整,因此我仍然可以采用文件路径/名称的 cmd 行参数。然后我改用 strtok 并跳过了数字,因此它只将城市名称输出到 txt 文件。谢谢大家的帮助!

    FILE *fpIn, *fpOut;
    if (!(fpIn = fopen(argv[1], "r"))) return -1;
    if (!(fpOut = fopen("theCities.txt", "w+"))) { fclose(fpIn); return -1; }
    while (fgets(flightInfo[i], 1024, fpIn) > 0)
    {
        clearTrailingCarraigeReturn(flightInfo[i]);
        // display the line we got from the fill
        printf("  >>> read record [%s]\n", flightInfo[i]);
    
        char *p = flightInfo[i];
        char *n = flightInfo[i];
        char *c = flightInfo[i];
        while(p != NULL)
        {
            p = strtok(p, ",");
            n = strtok(p, "[1-9]");
            c = strtok(p, ":");
            if (!p) break;
    
            while (n != NULL && c != NULL)
            {
                n = strtok(NULL, " ");
                c = strtok(NULL, " ");
            }
            fprintf(fpOut, "%s\n", p);
            p++;
            p = strtok(NULL, " ");
        }
        i++;
    
    }
    fclose(fpIn);
    fclose(fpOut);
    

    【讨论】:

    • strtok 是一种冒险的方法来解决您的问题,因为您不测试返回值。例如,如果该行不包含,,则内部循环中对strtok 的第二次调用具有未定义的行为。您应该将strcspn() 作为解析行的替代方法,它的优点是不修改行并且不需要使strtok() 不可重入的隐藏状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2019-05-23
    相关资源
    最近更新 更多