简体   繁体   English

如何在C语言中使用参数从文本文件中打印字符?

[英]How to print characters from text file, using arguments, in C?

I need to set an integer n using an argument -n that will be set as the amount of characters to print from the end of a given .txt file. 我需要使用参数-n设置整数n ,该参数将设置为从给定.txt文件末尾要打印的字符数。 This needs to be done without the <stdio.h> library as it is a homework piece about system calls. 这需要在没有<stdio.h>库的情况下完成,因为它是有关系统调用的家庭作业。

I have a program that is able to accept the argument -n and prints the amount of characters as specified by the user. 我有一个能够接受参数-n并输出用户指定字符数的程序。 It however prints an unreadable list of characters and NULLS after the required output and causes my terminal to malfunction. 但是,在所需的输出之后,它将打印出不可读的字符和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);
}

Note: this answer is an adaptation of the original answer to the first version of this question (now on hold) 注意:此答案是该问题第一版的原始答案的改编 (现已保留)

I need to set an integer n using an argument -n . 我需要使用参数-n设置整数n

Assuming the command line would look similar to prog.exe -n 4 , the arguments of main(int argc, char* argv[]) will be populated as: 假设命令行看起来类似于prog.exe -n 4 ,则main(int argc, char* argv[])将填充为:

argc == 3
argv[] == {"programName.exe", "-n", "4"}

argc could be reduced to 2 by either combining -n and 4 : -n4 , or eliminating the -n altogether, and just recognizing in the code that argv[1] (the 2nd argument) is a string representation of the value you need, and convert it to an int type. 可以通过将-n4组合在一起来将argc减少为2: -n4 ,或者完全消除-n ,然后在代码中认识到argv [1](第二个参数)是所需值的字符串表示形式,并将其转换为int类型。

Example: 例:

programName.exe 3

Then code it like this: 然后像这样编码:

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;
}

Some other general suggestions: 其他一些一般建议:

User input in general needs to be kept as predictable as possible. 通常,用户输入必须尽可能保持可预测性。 Be explicit when requesting what is acceptable for the user to enter, and reject anything that does not comply. 在要求用户输入可接受的内容时要明确,并拒绝不符合要求的内容。 Example, if a program is expecting a single digit argument, then force it to be just that, and reject everything else. 例如,如果程序期望一个数位的参数,则将其强制为正整数,并拒绝其他所有参数。 Given user input that does not comply: 给定不符合要求的用户输入:

prog.exe 3 4 5 程序3 4 5

detect in in the code: 在代码中检测:

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;

    }

    ...

Using portable functions (replacing lseek with fseek , and open with fopen , etc.) (read this for an example of the reason why ) here is an adaptation of your code that does what you described you needed it to do, including using the prog.exe -n <n> argument, ( argv == 3 ). 使用可移植函数(用fseek代替lseek ,并用fopenopen )(阅读示例以了解的原因 ),这里是代码的改编,可以完成您描述的工作,包括使用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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM