C++程序用输入重定向<运行报错,如何获取文件名输出?
解决方案
首先得搞清楚:./out < file.txt是Shell的输入重定向操作——Shell会直接把file.txt的内容喂给程序的标准输入(stdin),不会把file.txt当成命令行参数传给程序。你之前用argv[1]拿参数,这时候argv[1]根本是空的,不报错才怪。
下面分两种场景给你实现方法:
场景1:只需要读文件内容+输出固定提示
如果你的需求就是读file.txt里的字符串,同时输出Checking this file.txt,不需要自动识别文件名,直接改代码就行:
#include <iostream> #include <string> int main() { // 先输出你要的提示 std::cout << "Checking this file.txt\n"; // 从标准输入(现在就是file.txt的内容)读字符串 std::string line; while (std::getline(std::cin, line)) { // 这里处理读到的内容,比如打印出来 std::cout << "读到一行:" << line << '\n'; } return 0; }
编译运行命令不变:
g++ -g -std=c++11 main.cpp -o out ./out < file.txt
运行后先出Checking this file.txt,接着输出file.txt里的每一行内容。
场景2:需要自动识别重定向的文件名+读内容
如果想让程序自动识别重定向的文件名(比如换成./out < test.txt时,输出Checking this test.txt),在Linux下可以读/proc/self/fd/0这个符号链接(stdin对应的文件描述符是0):
#include <iostream> #include <string> #include <unistd.h> #include <limits.h> int main() { char filePath[PATH_MAX]; // 读取stdin对应的文件路径 ssize_t len = readlink("/proc/self/fd/0", filePath, PATH_MAX - 1); if (len != -1) { filePath[len] = '\0'; // 从完整路径里截取出文件名 std::string fullPath(filePath); size_t lastSlash = fullPath.find_last_of('/'); std::string fileName = (lastSlash != std::string::npos) ? fullPath.substr(lastSlash + 1) : fullPath; std::cout << "Checking this " << fileName << '\n'; } else { std::cerr << "没法获取输入文件名\n"; return 1; } // 读取文件内容 std::string line; while (std::getline(std::cin, line)) { std::cout << "读到一行:" << line << '\n'; } return 0; }
编译运行还是用原来的命令,这时候程序会自动识别重定向的文件名,输出对应的提示,再读内容。
注意:这种方法只在Linux下能用,Windows和macOS没有/proc文件系统。如果要跨平台,还是建议用./out file.txt这种命令行参数的方式,或者让用户先输入文件名再传内容。
内容的提问来源于stack exchange,提问作者Siraj Prince Motaung
相关产品推荐
相关产品推荐

