【问题标题】:get multiple inputs in one line C在一行中获得多个输入 C
【发布时间】:2023-03-08 00:26:01
【问题描述】:
int main(){
   
    
    char *inputFile;
    char *outputFile;
    int numberOfBuffer;
    int pageSize;
    printf("Enter four inpus, separated by spaces: ");
    scanf("%s %s B=%d P=%d", &inputFile,&outputFile,&numberOfBuffer,&pageSize);
    readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
    return 0;
}

我想通过输入命令行来读取输入并运行 readCSV() 方法

students.csv test.csv B=5 P=32

那行,但我的代码不起作用。有什么帮助吗? readCSV() 输入类型

readCSV(char* fileName,char* outputFileName, int numberOfBuffer, int pageSize)

【问题讨论】:

  • char *inputFile -> char inputFile[100]。阅读 C 教科书中处理字符串的章节。
  • 从不在 scanf 格式字符串中使用 "%s"。和gets一样糟糕。

标签: c input scanf


【解决方案1】:

您的大多数问题都是由误用 scanf 引起的。这里的解决方案不是修复你对 scanf 的使用,而是完全避免它。 (http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) 像这样的参数应该来自命令行参数,而不是来自输入流。让输入流保持清晰几乎总是更好的做法,这样它就可以用于收集数据。 (例如,将您的程序编写为过滤器。)例如:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void
check_prefix(const char *a, const char *prefix)
{
        if( strncmp(a, prefix, strlen(prefix)) ){
                fprintf(stderr, "Invalid argument: %s  Must start with, %s\n",
                         a, prefix);
                exit(EXIT_FAILURE);
        }
}

static void
readCSV(const char *in, const char *out, int n, int p)
{
        printf("in = %s, out = %s, n = %d, p = %d\n", in, out, n, p);
}

int
main(int argc, char **argv)
{
        if( argc < 5 ){
                fprintf(stderr, "Invalid number of arguments\n");
                return EXIT_FAILURE;
        }
        check_prefix(argv[3], "B=");
        check_prefix(argv[4], "P=");
        char *inputFile = argv[1];
        char *outputFile = argv[2];
        int numberOfBuffer = strtol(argv[3] + 2, NULL, 10);
        int pageSize = strtol(argv[4] + 2, NULL, 10);
        readCSV(inputFile, outputFile, numberOfBuffer, pageSize);
        return 0;
}

【讨论】:

    【解决方案2】:

    inputFileoutputFile 都需要声明为char数组,足以容纳预期的输入1

    #define MAX_FILE_NAME_LENGTH some-value
    ...
    char inputFile[MAX_FILE_NAME_LENGTH+1]; // +1 for string terminator
    char outputFile[MAX_FILE_NAME_LENGTH+1];
    

    然后在 scanf 调用中,notinputFileoutputFile 使用一元 &amp; 运算符 - 当您将 array 表达式传递为一个参数,它会自动转换为指向数组第一个元素的指针。您还想检查scanf 的结果,以确保您获得了所有输入:

    if ( scanf( "%s %s B=%d P=%d", inputFile, outputFile, &numberOfBuffer, &pageSize ) != 4 )
    {
      // bad input somewhere, probably with numberOfBuffer or pageSize,
      // handle as appropriate 
    }
    else
    {
      // process input normally
    }
    

    但是……

    scanf 是一个用于进行交互式输入的糟糕工具。很难做到防弹,对于这样的事情,你最好使用fgets或类似的东西将整个内容作为一个大字符串读取,然后从该字符串中提取数据。

    可以帮助您简化这一过程的一件事是,您不必在单个 scanf 调用中阅读整行。您可以单独阅读每个元素:

    /**
     * Start by reading the input file name; we use `fgets` instead
     * of `scanf` because it's easier to protect against a buffer overflow
     */
    if ( !fgets( inputFile, sizeof inputFile, stdin ) )
    {
      // error reading input file name, handle as appropriate
    } 
    /**
     * Successfully read inputFile, now read outputFile
     */
    else if ( !fgets( outputFile, sizeof outputFile, stdin ) )
    {
      // error reading output file name, handle as appropriate
    }
    /**
     * Now get the number of buffers - the leading blank in the format
     * string tells scanf to skip over any leading whitespace, otherwise 
     * if you have more than one blank between the end of the output file
     * name and the 'B' the read will fail.
     */
    else if ( scanf( " B=%d", &numberOfBuffer ) != 1 )
    {
      // error getting number of buffers, handle as appropriate
    }
    /**
     * And finally the page size, with the same leading blank space in the
     * format string. 
     */
    else if ( scanf( " P=%d", &pageSize ) != 1 )
    {
      // error getting page size, handle as appropriate
    }
    else
    {
      // process all inputs normally.
    }
    

    1. 或者他们的内存需要动态分配,但是当你刚刚学习 C 时,这是以后要解决的问题。

    【讨论】:

      【解决方案3】:

      您通过将错误类型的数据传递给scanf() 来调用未定义的行为%s 需要char*(指向具有足够长度的有效缓冲区),但您传递了char**

      您应该分配一些数组并将指针传递给它们。表达式中的数组(除了一些例外)会自动转换为指向其第一个元素的指针,因此您不需要为它们显式使用 &amp;

      您还应该指定要读取的最大长度(最多为缓冲区大小减去终止空字符的 1)以避免缓冲区溢出,并检查 scanf() 是否成功读取所有必需的内容。

      int main(){
          char inputFile[1024];
          char outputFile[1024];
          int numberOfBuffer;
          int pageSize;
          printf("Enter four inpus, separated by spaces: ");
          if(scanf("%1023s %1023s B=%d P=%d", inputFile,outputFile,&numberOfBuffer,&pageSize) != 4){
              fputs("read error\n", stderr);
              return 1;
          }
          readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-06-24
        • 1970-01-01
        • 1970-01-01
        • 2014-06-02
        • 2011-12-18
        • 1970-01-01
        • 2014-05-18
        • 2023-01-13
        • 2016-06-30
        相关资源
        最近更新 更多