在一行中获取多个输入 C

get multiple inputs in one line C

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)

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

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

您还应该指定要读取的最大长度(最大缓冲区大小减去终止空字符一)以避免缓冲区溢出并检查 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;
}

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

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

然后在 scanf 调用中,notinputFileoutputFile 使用一元 & 运算符 - 当您将 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,因此需要稍后解决。

您的大部分问题都是由于误用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;
}