神秘的 fopen() 问题

问题描述 投票:0回答:2

嗨,我正在使用 VSCode 在 Ubuntu 下编写 C 程序:

这里是完整的代码(它并没有按照置顶评论所说的去做,它只是应该打印出最后一行给

stdout
但是这里讨论的问题与其功能无关):

/*
    Usage: ./reverse [input] [output]

    Algorithm:
    Builds a linked list of strings, each for a line in [input],
    and then walk the nodes backward to build the [output]
*/

#include "stdio.h"
#include "stdlib.h"
#include <stdint.h>
#include <stdbool.h>

int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Usage: ./reverse [filename]\n");
        exit(EXIT_FAILURE);
    }
    // breakpoint set at next line
    char* filename = argv[1];
    FILE* fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("Cannot open file %s\n", filename);
        exit(EXIT_FAILURE);
    }
    // StackOverflow users please ignore the rest of the code
    // fseek() to the end of file and move back to find EOL
    int64_t offset = 1;
    int64_t offsetNextEOL = 0;
    int64_t offsetThisEOL = 0;
    while (true) {
        if (fseek(fp, -offset, SEEK_END) != 0) {
            fprintf(stderr, "fseek() error\n");
        }
        else {
            char ch = fgetc(fp);
            if (ch == '\n') {
                // print the last line to stdout
                offsetThisEOL = ftell(fp);
                if (offsetNextEOL < offsetThisEOL) {
                    // We just found the last EOL so print everything from it to EOF
                    if (fseek(fp, 0, SEEK_END) != 0) {
                        fprintf(stderr, "fseek() error\n");
                    }
                    int64_t offsetEOF = ftell(fp);
                    int64_t offsetDiff = offsetEOF - offsetThisEOL;
                    // Now seek back to offsetThisEOL and start print
                    if (fseek(fp, -offsetThisEOL, SEEK_END) != 0) {
                        fprintf(stderr, "fseek() error\n");
                    }
                    for (int64_t i = 0; i < offsetDiff; i++) {
                        printf("%c", fgetc(fp));
                    }
                    // For the last line, no need to print EOL

                    // We just found the last EOL so need to set up offsetNextEOL
                    offsetNextEOL = offsetThisEOL;
                }
                break;
            }
        }
        offset++;
    }

    exit(EXIT_SUCCESS);
}

文件夹结构如下所示(所有文件都在同一文件夹中):

-os
  -.vscode
  -utils
    reverse.c
    reverse
    reverse.txt

这是 launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
    {
        "name": "(gdb) Launch",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceRoot}/utils/reverse",
        "cwd": "${workspaceRoot}/utils",
        "args": ["reverse.txt"],
        "MIMode": "gdb",
        "setupCommands": [
            {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
            },
            {
                "description": "Set Disassembly Flavor to Intel",
                "text": "-gdb-set disassembly-flavor intel",
                "ignoreFailures": true
            }
        ]
    }
    ]
}

我在该行设置了一个断点:

char* filename = argv[1];

从调试器来看,

fopen()
函数有问题。真正令人沮丧的是,当我“介入”时,调试器只闪烁了三次,并且在退出代码 0 之前没有显示任何特别的东西。我认为路径一定有问题,但无法弄清楚。

出了什么问题?

c debugging fopen
2个回答
0
投票

我怀疑您要打开的文件不在exe所在的目录中。即 cwd 不是源目录。


0
投票

我对vscode一无所知,但我认为你的错误不在fopen;我复制粘贴了你的代码并在 fopen 之前和之后粘贴了 printf()s,并得到了它们。

看来您的问题是 vscode 的 json 或搜索逻辑。

stdio 和stdlib 上的“”很奇怪;如果您出于某种原因不这样做,可能会导致问题。

© www.soinside.com 2019 - 2024. All rights reserved.