如何在 C 中使用参数从文本文件中打印字符?
Posted
技术标签:
【中文标题】如何在 C 中使用参数从文本文件中打印字符?【英文标题】:How to print characters from text file, using arguments, in C? 【发布时间】:2019-12-31 22:51:33 【问题描述】:我需要使用参数-n
设置一个整数n
,该参数将设置为从给定.txt
文件末尾开始打印的字符数。这需要在没有 <stdio.h>
库的情况下完成,因为它是关于系统调用的家庭作业。
我有一个程序能够接受参数-n
并打印用户指定的字符数量。但是,它会在所需的输出之后打印一个不可读的字符列表和NULLS
,并导致我的终端出现故障。
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
//declaration of variables
char buf[1000];
int fd;
int n;
//initialising n to zero
n = 0;
//checking if the program run call is greater than one argument
if(argc > 1)
//if the second argument is equal to '-n' then take the 3rd argument (the int) and put it into n using stroll (string to long)
if(!strncmp(argv[1], "-n", 2))
n = atoi(argv[2]);
//if n has no set value from -n, set it to 200
if(n == 0)
n = 200;
// open the file for read only
fd = open("logfile.txt", O_RDONLY);
//Check if it can open and subsequent error handling
if(fd == -1)
char err[] = "Could not open the file";
write(STDERR_FILENO, err, sizeof(err)-1);
exit(1);
//use lseek to place pointer n characters from the end of file and then use read to write it to the buffer
lseek(fd, (n-(2*n)), SEEK_END);
read(fd, buf, n);
//write out to the standard output
write(STDOUT_FILENO, buf, sizeof(buf)-1);
//close the file fd and exit normally with code 0
close(fd);
exit(0);
return(0);
【问题讨论】:
明显与this question有关。n-(2*n)
那个奇怪的计算是什么?
调用read
读取字符时,始终捕获返回值:r = read(...)
。如果r
小于 0,则出现错误。如果 r
为 0,则您已到达文件末尾。如果r
大于0,则您已经阅读了一些字符,但是您应该使用r
的字符数而不是sizeof(buf)
(当然也不是sizeof(buf)-1
)。我怀疑这就是为什么你会得到奇怪的字符,但你忽略了“阅读”试图告诉你有问题的尝试。
如果文件中的最后一个字符不是换行符,那么你需要在退出程序之前输出一个换行符。顺便说一句,exit(0)
和 return(0)
做同样的事情(在main
)所以你只需要其中一个。
...和return 0;
很常见。请注意,与 exit(0)
不同,return 0;
不是函数。
【参考方案1】:
注意:此答案是对 first version of this question 的原始答案的改编(现在暂停)
我需要使用参数 -n 设置一个整数 n。
假设命令行类似于prog.exe -n 4
,main(int argc, char* argv[])
的参数将填充为:
argc == 3
argv[] == "programName.exe", "-n", "4"
argc
可以通过组合 -n
和 4
: -n4
或完全消除 -n
来减少到 2,并在代码中识别出 argv[1](第二个参数)是您需要的值的字符串表示形式,并将其转换为int
类型。
例子:
programName.exe 3
然后这样编码:
int main(int argc, char *argv[])
char *dummy;
int val;
if(argc != 2)
printf("Usage: prog.exe <n> where <n> is a positive integer value.\nProgram will now exit");
return 0;
// Resolve value of 2nd argument:
val = strtol(argv[1], &dummy, 10);
if (dummy == argv[1] || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
//handle error
//use val to read desired content from file
...
return 0;
其他一些一般性建议:
一般来说,用户输入需要尽可能地保持可预测性。在要求用户输入可接受的内容时要明确,并拒绝任何不符合要求的内容。例如,如果一个程序需要一个数字参数,那么强制它只是那个,并拒绝其他所有内容。给定不符合要求的用户输入:
prog.exe 3 4 5
在代码中检测:
int main(int argc, char *argv[])
int val = 0;
char *dummy = NULL;
if(argc != 2)
printf("Usage: prog.exe <n> - Where <n> is an integer with value > 0\n Program will now exit.");
return 0;
val = strtol(argv[1], &dummy, 10);
if (dummy == argv[1] || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
printf("Usage: prog.exe <n> - Where <n> is an integer with value > 0\n Program will now exit.");
return 0;
...
使用可移植函数(将lseek
替换为fseek
,将open
替换为fopen
等)(阅读this for an example of the reason why)这是对您的代码的改编你所描述的你需要它来做,包括使用prog.exe -n <n>
参数,(argv == 3
)。
int main(int argc, char *argv[])
char *dummy;
char buf[1000];
int n;
//initialising n to zero
n = 0;
//checking if the program run call is greater than one argument
if(argc != 3)
printf("Usage: prog.exe -n <n> - Where <n> is an integer with value > 0\n Program will now exit.");
return 0;
n = strtol(argv[2], &dummy, 10);
if (dummy == argv[2] || ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE))
printf("Usage: prog.exe <n> - Where <n> is an integer with value > 0\n Program will now exit.");
return 0;
// open the file for read only
FILE *fd = fopen(".\\data.txt", "r");
//Check if it can open and subsequent error handling
if(!fd)
char err[] = "Could not open the file";
fputs(err, stdout);
return 0;
//use lseek to place pointer n characters from the end of file and then use read to write it to the buffer
fseek(fd, (n-(2*n)), SEEK_END);
if(fgets(buf, n, fd))
//write out to the standard output
fwrite(buf, 1, n, stdout);
else
;//handle error
//close the file fd and exit normally with code 0
fclose(fd);
return(0);
【讨论】:
以上是关于如何在 C 中使用参数从文本文件中打印字符?的主要内容,如果未能解决你的问题,请参考以下文章