嗨,我正在使用 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 之前没有显示任何特别的东西。我认为路径一定有问题,但无法弄清楚。
出了什么问题?
我怀疑您要打开的文件不在exe所在的目录中。即 cwd 不是源目录。
我对vscode一无所知,但我认为你的错误不在fopen;我复制粘贴了你的代码并在 fopen 之前和之后粘贴了 printf()s,并得到了它们。
看来您的问题是 vscode 的 json 或搜索逻辑。
stdio 和stdlib 上的“”很奇怪;如果您出于某种原因不这样做,可能会导致问题。